mirror of
https://invent.kde.org/multimedia/kdenlive
synced 2025-12-07 16:59:59 +01:00
Compare commits
360 Commits
refactorin
...
v18.03.80
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b558147ba0 | ||
|
|
af633f74e8 | ||
|
|
59bc433af9 | ||
|
|
5b5e415834 | ||
|
|
b7259ad554 | ||
|
|
7d7a4efd09 | ||
|
|
88a21bdf44 | ||
|
|
4dcdcce3ff | ||
|
|
5a05e9d500 | ||
|
|
213e64339b | ||
|
|
af714cbdcd | ||
|
|
f36f1dc975 | ||
|
|
0c456f7fb2 | ||
|
|
ca468bc85b | ||
|
|
a33bd84d54 | ||
|
|
92b88c61ac | ||
|
|
bab0ebc50d | ||
|
|
9ca1cd57ca | ||
|
|
069e430ae4 | ||
|
|
02b7a19dfe | ||
|
|
94c420c85b | ||
|
|
ea185dfce6 | ||
|
|
3bc52cf369 | ||
|
|
41a9199800 | ||
|
|
5de2633cc5 | ||
|
|
62610f6114 | ||
|
|
6f47b64c6d | ||
|
|
86b7c0bc08 | ||
|
|
19d707d927 | ||
|
|
86c305de39 | ||
|
|
cd6717b4ee | ||
|
|
60916dd1fe | ||
|
|
91186164a8 | ||
|
|
5b33c563e2 | ||
|
|
77922b4ec8 | ||
|
|
423ba3b1d5 | ||
|
|
52bf301299 | ||
|
|
a20680186f | ||
|
|
276f61d09f | ||
|
|
e2d0e02efd | ||
|
|
862924d526 | ||
|
|
b6cdb35d3d | ||
|
|
a568c01505 | ||
|
|
5950ef6506 | ||
|
|
a0579e7834 | ||
|
|
856763adba | ||
|
|
0b3bc44566 | ||
|
|
f87ee28c0a | ||
|
|
f2b70a17c3 | ||
|
|
b5bac8ab36 | ||
|
|
102e588cfd | ||
|
|
d8e2777321 | ||
|
|
33931eee91 | ||
|
|
3f9180b5c0 | ||
|
|
4cfa2b978a | ||
|
|
6b63039e51 | ||
|
|
164f9fe0a6 | ||
|
|
0a12e90cb5 | ||
|
|
04ee4fa925 | ||
|
|
ec7da49c42 | ||
|
|
09d696b9c5 | ||
|
|
9041c04c52 | ||
|
|
181e5dd4b0 | ||
|
|
630f7bbfcf | ||
|
|
d2e26bb194 | ||
|
|
529e7a235b | ||
|
|
f4c9a045f2 | ||
|
|
f368c6448a | ||
|
|
4a7088e8b0 | ||
|
|
c98bbdffd1 | ||
|
|
48db9dad9c | ||
|
|
f372f318d6 | ||
|
|
6fef57061c | ||
|
|
04541ba0dd | ||
|
|
fdbbf21270 | ||
|
|
155a8c1bc1 | ||
|
|
36e0f91201 | ||
|
|
590a83fdc5 | ||
|
|
67b051577c | ||
|
|
61cf7cdf37 | ||
|
|
0d053c69bf | ||
|
|
67c4958b65 | ||
|
|
0fba2e0643 | ||
|
|
012d1cfeb8 | ||
|
|
db856a5cd3 | ||
|
|
d6cea2efee | ||
|
|
2c2c6a32e0 | ||
|
|
a692f3bb8c | ||
|
|
ecbc0967fd | ||
|
|
5fb0e4a5b8 | ||
|
|
e4c764483f | ||
|
|
16690444c2 | ||
|
|
596163833d | ||
|
|
42cc3b0ebc | ||
|
|
cbb224784f | ||
|
|
28a7d4bd33 | ||
|
|
bb14c0739c | ||
|
|
e6a6fc62e3 | ||
|
|
4cac44220e | ||
|
|
5e0b0db076 | ||
|
|
60712faceb | ||
|
|
53f612a22b | ||
|
|
e0473f8619 | ||
|
|
7ecca09acc | ||
|
|
793f549770 | ||
|
|
f863490fea | ||
|
|
38b3aec21d | ||
|
|
e7db0285ef | ||
|
|
e20cb65f34 | ||
|
|
2bda800f9e | ||
|
|
3421356529 | ||
|
|
a2b0d69931 | ||
|
|
ff8ecee321 | ||
|
|
fa77da1742 | ||
|
|
e9979ffd0e | ||
|
|
45a8b68328 | ||
|
|
832e699b52 | ||
|
|
92698a3685 | ||
|
|
da98113f10 | ||
|
|
33264f9a98 | ||
|
|
02f86a8725 | ||
|
|
7d719ca802 | ||
|
|
078dc8d1e0 | ||
|
|
703360538d | ||
|
|
3d1beab793 | ||
|
|
4ca32b4d22 | ||
|
|
915970c1aa | ||
|
|
4c3c8ccb37 | ||
|
|
5a51022496 | ||
|
|
ae4c544f6f | ||
|
|
40faa0eb2c | ||
|
|
9e288db02d | ||
|
|
2ed43d34a1 | ||
|
|
ad694e0477 | ||
|
|
72c75b7772 | ||
|
|
8958d7df24 | ||
|
|
c88f51af7c | ||
|
|
9ffa5e6d79 | ||
|
|
e6dc4cb368 | ||
|
|
7f56a6f0f1 | ||
|
|
d79c3cb16c | ||
|
|
a153154910 | ||
|
|
0120221193 | ||
|
|
8b48e2d4a3 | ||
|
|
0c6a4327d3 | ||
|
|
960ae4650b | ||
|
|
9a86cb15da | ||
|
|
735d1ab7cc | ||
|
|
0ab3c46794 | ||
|
|
0defb20de9 | ||
|
|
26f17f6bf0 | ||
|
|
668592c6e7 | ||
|
|
f69dd4083c | ||
|
|
5eceeba1f5 | ||
|
|
65778d9f0f | ||
|
|
aa80c88cc4 | ||
|
|
ec09e5e54c | ||
|
|
94b1b432ec | ||
|
|
8f788c1d13 | ||
|
|
4d7a3a6dd6 | ||
|
|
0156e1e417 | ||
|
|
118ce7d1d9 | ||
|
|
9dc38dd769 | ||
|
|
11726f8764 | ||
|
|
3ab863f0d5 | ||
|
|
6435a4ebdb | ||
|
|
b965270152 | ||
|
|
55c1ee1c7b | ||
|
|
9675c27073 | ||
|
|
b4e74ad93c | ||
|
|
1834b9a96e | ||
|
|
b8a83d2b68 | ||
|
|
ec69039673 | ||
|
|
fe684e7eb3 | ||
|
|
456635ac2c | ||
|
|
209e4fccb5 | ||
|
|
3404da90de | ||
|
|
414d6579a1 | ||
|
|
673d0f79ed | ||
|
|
7cf9980c1f | ||
|
|
e8d6b75c36 | ||
|
|
9f01d93689 | ||
|
|
984df727b9 | ||
|
|
6f5584eee1 | ||
|
|
74a0be8d8b | ||
|
|
c92aa046c9 | ||
|
|
42a40132a1 | ||
|
|
b09224eee3 | ||
|
|
4724bb8b4d | ||
|
|
d33d59c234 | ||
|
|
8ec829f1b6 | ||
|
|
80e0b44f18 | ||
|
|
e4e8207552 | ||
|
|
020eb7bea1 | ||
|
|
cb89fe494c | ||
|
|
388d983390 | ||
|
|
478589576b | ||
|
|
6766aec23d | ||
|
|
3e5598b2a4 | ||
|
|
b1c5738a6e | ||
|
|
79a0a88912 | ||
|
|
359220c9ce | ||
|
|
a2b2d50586 | ||
|
|
66cfda93ce | ||
|
|
7c237457f6 | ||
|
|
df840cdf26 | ||
|
|
d961c39bd8 | ||
|
|
f99275fabe | ||
|
|
b279de93be | ||
|
|
d0753238c0 | ||
|
|
243dff060b | ||
|
|
78a1d89f40 | ||
|
|
3d53f18644 | ||
|
|
2fd4a6c711 | ||
|
|
425efbbbbe | ||
|
|
8d2c091641 | ||
|
|
723988783c | ||
|
|
d3aa4cb6e4 | ||
|
|
d9ecb0751b | ||
|
|
8e054c9a52 | ||
|
|
6665d7fb41 | ||
|
|
1c741db4fd | ||
|
|
92e561d10f | ||
|
|
e84bbd0ac8 | ||
|
|
8d9c04ab8f | ||
|
|
8e2d00e30b | ||
|
|
9dc324c468 | ||
|
|
ab8c2381ae | ||
|
|
74cf8fa64d | ||
|
|
0b5be0aa3d | ||
|
|
2c88d42bd5 | ||
|
|
ef61b5adf2 | ||
|
|
f3d6aa2dc3 | ||
|
|
3c90778b2d | ||
|
|
a9b53833ed | ||
|
|
4a5cbe22ea | ||
|
|
53133bd07d | ||
|
|
6707f48a19 | ||
|
|
8034bd3423 | ||
|
|
243545e4f0 | ||
|
|
cfef990488 | ||
|
|
1e4dc2803e | ||
|
|
9674c1fe6a | ||
|
|
35af0b4af8 | ||
|
|
6bb4769193 | ||
|
|
5f6cc24d62 | ||
|
|
463e9f8453 | ||
|
|
dc80cd7352 | ||
|
|
9d9010b017 | ||
|
|
dbc6793d3f | ||
|
|
76ceba1640 | ||
|
|
0f1f490cfc | ||
|
|
2a93b292e3 | ||
|
|
28816933a3 | ||
|
|
d85742fcb1 | ||
|
|
d68e3ad873 | ||
|
|
0e3f823288 | ||
|
|
4cc55c1e71 | ||
|
|
67890f6e58 | ||
|
|
5becbfc25e | ||
|
|
4d1b876722 | ||
|
|
e05d4a5120 | ||
|
|
62a6a93d99 | ||
|
|
3086e18529 | ||
|
|
e6f89c5336 | ||
|
|
94f9c53ca4 | ||
|
|
6bae786fa8 | ||
|
|
d198819b03 | ||
|
|
cc849dd090 | ||
|
|
14ff0d088e | ||
|
|
8a5f3217ab | ||
|
|
b43c82a697 | ||
|
|
f874d52901 | ||
|
|
1ea8ed36a1 | ||
|
|
38f6ab61d1 | ||
|
|
c7002c08ef | ||
|
|
8f68095d67 | ||
|
|
646fbd0288 | ||
|
|
ee9f3a4b1b | ||
|
|
aada055669 | ||
|
|
b6a4be7f01 | ||
|
|
de9abfd108 | ||
|
|
08b6b94bd3 | ||
|
|
98a2b68389 | ||
|
|
9cf0415590 | ||
|
|
085a178ab4 | ||
|
|
dbee17e590 | ||
|
|
2d44d6e2b1 | ||
|
|
5957d784c8 | ||
|
|
bcd643f27a | ||
|
|
8a56722c36 | ||
|
|
194880b170 | ||
|
|
5994a8172e | ||
|
|
3de068e389 | ||
|
|
7d2676f4a0 | ||
|
|
caac06125f | ||
|
|
86ab24b0fd | ||
|
|
b5a6cd8557 | ||
|
|
bc796a104f | ||
|
|
aba3aaf852 | ||
|
|
6fc5a7eab5 | ||
|
|
8b9fc20160 | ||
|
|
640d446755 | ||
|
|
57a346a99f | ||
|
|
6ceb498924 | ||
|
|
7d1d20ab23 | ||
|
|
4ca81a4b6f | ||
|
|
a6ac89e1ad | ||
|
|
93fb8a9388 | ||
|
|
6edd85105a | ||
|
|
f248ea0d64 | ||
|
|
6bb2cedaaa | ||
|
|
2a94842ed5 | ||
|
|
285493dc9b | ||
|
|
aac49a1052 | ||
|
|
d6c6f4b88d | ||
|
|
a5490e5609 | ||
|
|
018de76858 | ||
|
|
3963244907 | ||
|
|
9792a1b1cd | ||
|
|
6d71034c43 | ||
|
|
885fb4d0eb | ||
|
|
b34d0c0bb5 | ||
|
|
716c03967a | ||
|
|
adbdc888eb | ||
|
|
67257981b1 | ||
|
|
e844edc049 | ||
|
|
be60096748 | ||
|
|
91b268c272 | ||
|
|
323903cc4e | ||
|
|
7f9acd934c | ||
|
|
ccf1c9cda5 | ||
|
|
436cccdb3c | ||
|
|
3d113980ac | ||
|
|
fab234a0ca | ||
|
|
de5076402c | ||
|
|
464b1932ad | ||
|
|
048a3d7464 | ||
|
|
9aca0ee731 | ||
|
|
f540402274 | ||
|
|
ccf21435d5 | ||
|
|
b9ccc837ef | ||
|
|
901c3ecfd2 | ||
|
|
7038cc063d | ||
|
|
754b8eeed8 | ||
|
|
b4aff4564b | ||
|
|
e5e7c6dad2 | ||
|
|
8a20fca86e | ||
|
|
ad861ecce2 | ||
|
|
5bb59c18fa | ||
|
|
a76a3d15b2 | ||
|
|
5beb03dc62 | ||
|
|
54e3d416b6 | ||
|
|
0ce898669a | ||
|
|
00e8696417 | ||
|
|
65681183e2 | ||
|
|
df419e2f77 | ||
|
|
91bd4db97d | ||
|
|
20a6397a72 | ||
|
|
0eb1d1ef8f |
4
.arcconfig
Normal file
4
.arcconfig
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"project.name" : "Kdenlive",
|
||||
"phabricator.uri" : "https://phabricator.kde.org/"
|
||||
}
|
||||
@@ -4,9 +4,9 @@ project(Kdenlive)
|
||||
# stable release. An additional number can be used for bugfix-only releases.
|
||||
|
||||
# KDE Application Version, managed by release script
|
||||
set (KDE_APPLICATIONS_VERSION_MAJOR "17")
|
||||
set (KDE_APPLICATIONS_VERSION_MAJOR "18")
|
||||
set (KDE_APPLICATIONS_VERSION_MINOR "03")
|
||||
set (KDE_APPLICATIONS_VERSION_MICRO "70")
|
||||
set (KDE_APPLICATIONS_VERSION_MICRO "80")
|
||||
|
||||
set(KDENLIVE_VERSION ${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO})
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
@@ -18,20 +18,20 @@ if (POLICY CMP0053)
|
||||
endif()
|
||||
# Minimum versions of main dependencies.
|
||||
set(MLT_MIN_MAJOR_VERSION 6)
|
||||
set(MLT_MIN_MINOR_VERSION 0)
|
||||
set(MLT_MIN_MINOR_VERSION 6)
|
||||
set(MLT_MIN_PATCH_VERSION 0)
|
||||
set(MLT_MIN_VERSION ${MLT_MIN_MAJOR_VERSION}.${MLT_MIN_MINOR_VERSION}.${MLT_MIN_PATCH_VERSION})
|
||||
|
||||
set(QT_MIN_VERSION 5.5.0)
|
||||
set(QT_MIN_VERSION 5.6.0)
|
||||
|
||||
find_package(ECM 5.21.0 REQUIRED CONFIG)
|
||||
find_package(ECM 5.18.0 REQUIRED CONFIG)
|
||||
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake/modules)
|
||||
include(KDECompilerSettings NO_POLICY_SCOPE)
|
||||
include(FeatureSummary)
|
||||
include(ECMInstallIcons)
|
||||
include(GenerateExportHeader)
|
||||
include(KDEInstallDirs)
|
||||
include(KDECMakeSettings)
|
||||
include(KDECompilerSettings)
|
||||
include(ECMOptionalAddSubdirectory)
|
||||
include(ECMMarkNonGuiExecutable)
|
||||
include(ECMAddAppIcon)
|
||||
@@ -43,7 +43,6 @@ add_definitions(-DTRANSLATION_DOMAIN=\"kdenlive\")
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${ECM_MODULE_PATH})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
# To be switched on when releasing.
|
||||
option(RELEASE_BUILD "Remove Git revision from program version (use for stable releases)" ON)
|
||||
|
||||
@@ -91,8 +90,8 @@ else()
|
||||
endif()
|
||||
|
||||
find_package(KF5 REQUIRED COMPONENTS Archive Bookmarks CoreAddons Config ConfigWidgets
|
||||
DBusAddons KIO WidgetsAddons NotifyConfig NewStuff XmlGui Notifications GuiAddons TextWidgets IconThemes Crash
|
||||
OPTIONAL_COMPONENTS DocTools FileMetaData)
|
||||
DBusAddons KIO WidgetsAddons NotifyConfig NewStuff XmlGui Notifications GuiAddons TextWidgets IconThemes
|
||||
OPTIONAL_COMPONENTS DocTools FileMetaData Crash)
|
||||
|
||||
if (KF5FileMetaData_FOUND)
|
||||
message(STATUS "Found KF5 FileMetadata to extract file metadata")
|
||||
@@ -116,12 +115,14 @@ if(KF5DocTools_FOUND)
|
||||
add_subdirectory(doc)
|
||||
endif()
|
||||
#add_subdirectory(plugins)
|
||||
ecm_optional_add_subdirectory(po)
|
||||
add_subdirectory(renderer)
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(thumbnailer)
|
||||
#add_subdirectory(testingArea)
|
||||
|
||||
ki18n_install(po)
|
||||
if (KF5DocTools_FOUND)
|
||||
kdoctools_install(po)
|
||||
endif()
|
||||
|
||||
install( FILES kdenlive.categories DESTINATION ${KDE_INSTALL_CONFDIR} )
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_check_modules(PC_MLT QUIET mlt++)
|
||||
pkg_check_modules(PC_MLT mlt++)
|
||||
|
||||
find_path(MLT_INCLUDE_DIR
|
||||
NAMES framework/mlt.h
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# Find QJSON - JSON handling library for Qt
|
||||
#
|
||||
# This module defines
|
||||
# QJSON_FOUND - whether the qsjon library was found
|
||||
# QJSON_LIBRARIES - the qjson library
|
||||
# QJSON_INCLUDE_DIR - the include path of the qjson library
|
||||
#
|
||||
# Copyright (c) 2010 Pino Toscano, <toscano.pino@tiscali.it>
|
||||
#
|
||||
# Redistribution and use is allowed according to the terms of the BSD license.
|
||||
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
|
||||
|
||||
|
||||
|
||||
if (QJSON_INCLUDE_DIR AND QJSON_LIBRARIES)
|
||||
|
||||
# Already in cache
|
||||
set (QJSON_FOUND TRUE)
|
||||
|
||||
else (QJSON_INCLUDE_DIR AND QJSON_LIBRARIES)
|
||||
|
||||
if (NOT WIN32)
|
||||
# use pkg-config to get the values of QJSON_INCLUDE_DIRS
|
||||
# and QJSON_LIBRARY_DIRS to add as hints to the find commands.
|
||||
include (FindPkgConfig)
|
||||
pkg_check_modules (PC_QJSON REQUIRED QJson>=0.5)
|
||||
endif (NOT WIN32)
|
||||
|
||||
find_library (QJSON_LIBRARIES
|
||||
NAMES
|
||||
qjson
|
||||
PATHS
|
||||
${PC_QJSON_LIBRARY_DIRS}
|
||||
${LIB_INSTALL_DIR}
|
||||
${KDE4_LIB_DIR}
|
||||
)
|
||||
|
||||
find_path (QJSON_INCLUDE_DIR
|
||||
NAMES
|
||||
qjson/parser.h
|
||||
PATHS
|
||||
${PC_QJSON_INCLUDE_DIRS}
|
||||
${INCLUDE_INSTALL_DIR}
|
||||
${KDE4_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(QJSON DEFAULT_MSG QJSON_LIBRARIES QJSON_INCLUDE_DIR)
|
||||
|
||||
endif (QJSON_INCLUDE_DIR AND QJSON_LIBRARIES)
|
||||
@@ -34,7 +34,7 @@ install(FILES
|
||||
# kdenlivemonitorsplit.qml
|
||||
DESTINATION ${DATA_INSTALL_DIR}/kdenlive)
|
||||
install(FILES kdenlive.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR})
|
||||
install(FILES kdenlive_projectprofiles.knsrc kdenlive_renderprofiles.knsrc kdenlive_wipes.knsrc kdenlive_titles.knsrc DESTINATION ${CONFIG_INSTALL_DIR})
|
||||
install(FILES kdenlive_renderprofiles.knsrc kdenlive_wipes.knsrc kdenlive_titles.knsrc DESTINATION ${CONFIG_INSTALL_DIR})
|
||||
install(FILES profiles.xml DESTINATION ${DATA_INSTALL_DIR}/kdenlive/export)
|
||||
install(FILES org.kde.kdenlive.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
|
||||
install(FILES org.kde.kdenlive.desktop DESTINATION ${XDG_APPS_INSTALL_DIR})
|
||||
|
||||
@@ -110,7 +110,7 @@ The rest:
|
||||
- url/path
|
||||
- represented by button to open "file open" dialog
|
||||
- additional attributes:
|
||||
- "filter": Filter for file extensions. Example : "*.cpp *.cc *.C|C++ Source Files\n*.h *.H|Header files" or as using mimetype: "image/png text/html"
|
||||
- "filter": Filter for file extensions. Example : "*.cpp *.cc *.C|C++ Source Files\n*.h *.H|Header files" or as using MIME type: "image/png text/html"
|
||||
- "wipe":
|
||||
- special GUI for the wipe transition makes it possible to select a direction of a slide
|
||||
- "addedgeometry":
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<!DOCTYPE kpartgui>
|
||||
<group>
|
||||
<effect tag="qtblend" id="qtblend">
|
||||
<name>Transform</name>
|
||||
<description>Position, scale and opacity.</description>
|
||||
@@ -17,5 +18,27 @@
|
||||
<name>Distort</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
<effect tag="qtblend" id="qtblend" version="2">
|
||||
<name>Transform</name>
|
||||
<description>Position, scale and opacity.</description>
|
||||
<author>Jean-Baptiste Mardelle</author>
|
||||
<parameter type="animatedrect" name="rect" default="0 0 %width %height 1">
|
||||
<name>Rectangle</name>
|
||||
</parameter>
|
||||
<parameter type="animated" name="rotation" max="360" min="-360" default="0" notintimeline="1">
|
||||
<name>Rotation</name>
|
||||
</parameter>
|
||||
<parameter type="list" name="compositing" default="0" paramlist="0;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;6;8">
|
||||
<paramlistdisplay>Alpha blend,Xor,Plus,Multiply,Screen,Overlay,Darken,Lighten,Color dodge,Color burn,Hard light,Soft light,Difference,Exclusion,Bitwise or,Bitwise and,Bitwise xor,Bitwise nor,Bitwise nand,Bitwise not xor,Destination in,Destination out</paramlistdisplay>
|
||||
<name>Compositing</name>
|
||||
</parameter>
|
||||
<parameter type="bool" name="distort" default="0" min="0" max="1">
|
||||
<name>Distort</name>
|
||||
</parameter>
|
||||
<parameter type="bool" name="rotate_center" default="1" min="0" max="1">
|
||||
<name>Rotate from center</name>
|
||||
</parameter>
|
||||
</effect>
|
||||
</group>
|
||||
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@ DNxHD=vcodec=dnxhd vb=145000k acodec=pcm_s16le threads=%threads;mov
|
||||
MPEG=qscale=4 ab=192k vcodec=mpeg2video acodec=mp2 threads=%threads;mpg
|
||||
|
||||
[proxy]
|
||||
x264=-vf scale=640:-1 -g 5 -crf 25 -ab 128k -vcodec libx264 -acodec libvorbis -preset veryfast;mov
|
||||
MPEG=-vf scale=640:-1 -g 5 -qscale 6 -ab 128k -vcodec mpeg2video -acodec mp2;mpg
|
||||
x264=-vf scale=960:-2 -g 1 -bf 0 -vb 0 -crf 20 -vcodec libx264 -ab 128k -acodec aac -preset veryfast;mov
|
||||
MPEG2=-vf scale=960:-2 -g 1 -bf 0 -vb 0 -qscale 6 -ab 128k -vcodec mpeg2video -acodec ac3;mpg
|
||||
MJPEG=-vf yadif,scale=960:-2 -qscale 3 -vcodec mjpeg -acodec pcm_s16le;mkv
|
||||
|
||||
[screengrab]
|
||||
X264 mute=-crf 25 -vcodec libx264 -preset veryfast -threads 0;mov
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[Global]
|
||||
IconName=kdenlive
|
||||
Comment=Kdenlive
|
||||
Comment[ar]=كدينلايڤ
|
||||
Comment[ast]=Kdenlive
|
||||
Comment[bs]=Kdenlive
|
||||
Comment[ca]=Kdenlive
|
||||
@@ -20,6 +21,7 @@ Comment[hu]=Kdenlive
|
||||
Comment[it]=Kdenlive
|
||||
Comment[ja]=Kdenlive
|
||||
Comment[km]=Kdenlive
|
||||
Comment[ko]=Kdenlive
|
||||
Comment[lt]=Kdenlive
|
||||
Comment[lv]=Kdenlive
|
||||
Comment[mr]=के-डि-एनलाइव्ह
|
||||
@@ -57,11 +59,12 @@ Name[es]=Procesamiento finalizado
|
||||
Name[et]=Renderdamine on valmis
|
||||
Name[fi]=Renderöinti valmistui
|
||||
Name[fr]=Rendu terminé
|
||||
Name[gl]=Renderizado finalizado
|
||||
Name[gl]=Rematou a renderización
|
||||
Name[hu]=A renderelés befejeződött
|
||||
Name[it]=Esportazione terminata
|
||||
Name[ja]=レンダリングが完了しました
|
||||
Name[km]=បានបញ្ចប់ការបង្ហាញ
|
||||
Name[ko]=렌더링 완료됨
|
||||
Name[lt]=Atvaizdavimas baigtas
|
||||
Name[lv]=Renderēšana pabeigta
|
||||
Name[mr]=रेंडरींग पूर्ण झाले
|
||||
@@ -85,7 +88,7 @@ Comment[ar]=قد انتهى التّصيير
|
||||
Comment[bs]=Iscrtavanje je gotovo
|
||||
Comment[ca]=La renderització ja ha acabat
|
||||
Comment[ca@valencia]=La renderització ja ha acabat
|
||||
Comment[cs]=Renderování je hotové
|
||||
Comment[cs]=Renderování je u konce
|
||||
Comment[da]=Renderingen er slut
|
||||
Comment[de]=Das Rendern ist beendet
|
||||
Comment[el]=Η αποτύπωση τελείωσε
|
||||
@@ -94,18 +97,19 @@ Comment[es]=El procesamiento ha finalizado
|
||||
Comment[et]=Renderdamine on valmis
|
||||
Comment[fi]=Renderöinti on tehty
|
||||
Comment[fr]=Le rendu est terminé
|
||||
Comment[gl]=Rematou o renderizado
|
||||
Comment[gl]=Rematou a renderización
|
||||
Comment[hu]=A renderelésnek vége
|
||||
Comment[it]=L'esportazione è terminata
|
||||
Comment[ja]=レンダリングが終了しました
|
||||
Comment[km]=ការបង្ហាញបានចប់
|
||||
Comment[ko]=렌더링이 끝났음
|
||||
Comment[lt]=Atvaizdavimas baigtas
|
||||
Comment[lv]=Renderēšana ir beigusies
|
||||
Comment[mr]=रेंडरींग पूर्ण झाले आहे
|
||||
Comment[nb]=Ferdig med opptegning
|
||||
Comment[nl]=Weergave uitwerken is gereed
|
||||
Comment[nn]=Videorendering er ferdig
|
||||
Comment[pl]=Ukończono zostało zakończone
|
||||
Comment[pl]=Renderowanie zostało zakończone
|
||||
Comment[pt]=A geração terminou
|
||||
Comment[pt_BR]=A renderização foi terminada
|
||||
Comment[ro]=Randarea s-a încheiat
|
||||
@@ -134,11 +138,12 @@ Name[es]=Procesamiento inciado
|
||||
Name[et]=Renderdamist on alustatud
|
||||
Name[fi]=Renderöinti aloitettu
|
||||
Name[fr]=Rendu démarré
|
||||
Name[gl]=Iniciado o renderizado
|
||||
Name[gl]=Comezou a renderización
|
||||
Name[hu]=A renderelés elkezdődött
|
||||
Name[it]=Esportazione avviata
|
||||
Name[ja]=レンダリングを開始しました
|
||||
Name[km]=ការបង្ហាញបានចាប់ផ្ដើម
|
||||
Name[ko]=렌더링 시작됨
|
||||
Name[lt]=Atvaizdavimas pradėtas
|
||||
Name[lv]=Renderēšana sākta
|
||||
Name[mr]=रेंडरींग सुरु झाले
|
||||
@@ -162,7 +167,7 @@ Comment[ar]=قد بدأ التّصيير
|
||||
Comment[bs]=Iscrtavanje je započelo
|
||||
Comment[ca]=La renderització ja ha començat
|
||||
Comment[ca@valencia]=La renderització ja ha començat
|
||||
Comment[cs]=Renderování bylo začato
|
||||
Comment[cs]=Vykreslování bylo zahájeno
|
||||
Comment[da]=Renderingen blev startet
|
||||
Comment[de]=Das Rendern wurde gestartet
|
||||
Comment[el]=Η αποτύπωση ξεκίνησε
|
||||
@@ -171,11 +176,12 @@ Comment[es]=El procesamiento ha sido iniciado
|
||||
Comment[et]=Renderdamist on alustatud
|
||||
Comment[fi]=Renderöinti aloitettiin
|
||||
Comment[fr]=Le rendu a démarré
|
||||
Comment[gl]=Vaise iniciar o renderizado
|
||||
Comment[gl]=Comezou a renderización
|
||||
Comment[hu]=A renderelés elkezdődött
|
||||
Comment[it]=L'esportazione è stata avviata
|
||||
Comment[ja]=レンダリングを開始しました
|
||||
Comment[km]=ការបង្ហាញត្រូវបានចាប់ផ្ដើម
|
||||
Comment[ko]=렌더링이 시작됨
|
||||
Comment[lt]=Atvaizdavimas buvo pradėtas
|
||||
Comment[lv]=Renderēšana tika palaista
|
||||
Comment[mr]=रेंडरींग सुरु झाले होते
|
||||
@@ -203,7 +209,7 @@ Name[bs]=Kadar uhvaćen
|
||||
Name[ca]=S'ha capturat un fotograma
|
||||
Name[ca@valencia]=S'ha capturat un fotograma
|
||||
Name[cs]=Snímek zachycen
|
||||
Name[da]=Billed indfanget
|
||||
Name[da]=Billede indfanget
|
||||
Name[de]=Bild aufgenommen
|
||||
Name[el]=Σύλληψη πλαισίου
|
||||
Name[en_GB]=Frame captured
|
||||
@@ -216,6 +222,7 @@ Name[hu]=Képkocka rögzítve
|
||||
Name[it]=Fotogramma acquisito
|
||||
Name[ja]=フレームをキャプチャしました
|
||||
Name[km]=បានចាប់យកស៊ុម
|
||||
Name[ko]=프레임 캡처됨
|
||||
Name[lt]=Kadras išsaugotas
|
||||
Name[lv]=Kadrs notverts
|
||||
Name[mr]=फ्रेम पकडली
|
||||
@@ -240,7 +247,7 @@ Comment[bs]=Kadar je uhvaćen na disk
|
||||
Comment[ca]=S'ha capturat i desat un fotograma al disc
|
||||
Comment[ca@valencia]=S'ha capturat i guardat un fotograma al disc
|
||||
Comment[cs]=Snímek byl zachycen na disk
|
||||
Comment[da]=Et billed blev indfanget til disken
|
||||
Comment[da]=Et billede blev indfanget til disken
|
||||
Comment[de]=Ein Bild wurde aufgenommen und auf die Festplatte gespeichert
|
||||
Comment[el]=Έγινε σύλληψη πλαισίου στο δίσκο
|
||||
Comment[en_GB]=A frame was captured to disk
|
||||
@@ -253,6 +260,7 @@ Comment[hu]=Egy képkocka rögzítésre került a lemezre
|
||||
Comment[it]=È stato acquisito un fotogramma sul disco
|
||||
Comment[ja]=フレームをディスクにキャプチャしました
|
||||
Comment[km]=ស៊ុមត្រូវបានចាប់យកទៅកាន់ថាស
|
||||
Comment[ko]=프레임이 디스크에 캡처됨
|
||||
Comment[lt]=Kadras buvo išsaugotas į diską
|
||||
Comment[lv]=Kadrs tika notverts diskā
|
||||
Comment[mr]=फ्रेम डिस्कवर पकडली
|
||||
@@ -294,6 +302,7 @@ Name[hu]=Kezdődhet a rögzítés
|
||||
Name[it]=Pronto per la registrazione
|
||||
Name[ja]=キャプチャ準備完了
|
||||
Name[km]=រួចរាល់ដើម្បីចាប់យក
|
||||
Name[ko]=캡처 준비
|
||||
Name[lt]=Pasiruošęs išsaugoti
|
||||
Name[lv]=Gatavs notveršanai
|
||||
Name[mr]=पकडण्याकरिता तयार
|
||||
@@ -336,6 +345,7 @@ Name[hu]=Hiba
|
||||
Name[it]=Errore
|
||||
Name[ja]=エラー
|
||||
Name[km]=កំហុស
|
||||
Name[ko]=오류
|
||||
Name[lt]=Klaida
|
||||
Name[lv]=Kļūda
|
||||
Name[mr]=त्रुटी
|
||||
@@ -358,11 +368,12 @@ Name[x-test]=xxErrorxx
|
||||
Name[zh_CN]=错误
|
||||
Name[zh_TW]=錯誤
|
||||
Comment=An error occurred in Kdenlive
|
||||
Comment[ar]=حدث خطأ في «كدينلايڤ»
|
||||
Comment[bs]=Desila se greška u KDenlive
|
||||
Comment[ca]=S'ha produït un error al Kdenlive
|
||||
Comment[ca@valencia]=S'ha produït un error al Kdenlive
|
||||
Comment[cs]=V Kdenlive došlo k chybě
|
||||
Comment[da]=En fejl opstod i Kdenlive
|
||||
Comment[da]=Der opstod en fejl i Kdenlive
|
||||
Comment[de]=In Kdenlive ist ein Fehler aufgetreten
|
||||
Comment[el]=Εμφανίστηκε σφάλμα στο Kdenlive
|
||||
Comment[en_GB]=An error occurred in Kdenlive
|
||||
@@ -376,6 +387,7 @@ Comment[hu]=Hiba történt a Kdenlive-ban
|
||||
Comment[it]=Si è verificato un errore in Kdenlive
|
||||
Comment[ja]=Kdenlive 内でエラーが発生
|
||||
Comment[km]=មានកំហុសបានកើតឡើងនៅក្នុង Kdenlive
|
||||
Comment[ko]=Kdenlive에서 오류가 발생함
|
||||
Comment[lt]=Įvyko Kdenlive klaida
|
||||
Comment[lv]=Programmā Kdenlive radās kļūda
|
||||
Comment[mr]=के-डि-एनलाइव्ह मध्ये त्रुटी निर्माण झाली
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
|
||||
<mime-type type="application/x-kdenlive">
|
||||
<comment>Kdenlive video project document</comment>
|
||||
<comment xml:lang="ar">مستند مشروع «كدينلايڤ» ڤديوهيّ</comment>
|
||||
<comment xml:lang="ast">Documentu de proyeutu de videu Kdenlive</comment>
|
||||
<comment xml:lang="bs">Kdenlive video projekt dokument</comment>
|
||||
<comment xml:lang="ca">document de projecte de vídeo del Kdenlive</comment>
|
||||
@@ -13,6 +14,7 @@
|
||||
<comment xml:lang="en_GB">Kdenlive video project document</comment>
|
||||
<comment xml:lang="es">Documento de proyecto de video de Kdenlive</comment>
|
||||
<comment xml:lang="et">Kdenlive'i videoprojekti dokument</comment>
|
||||
<comment xml:lang="eu">Kdenlive bideo proiektu dokumentua</comment>
|
||||
<comment xml:lang="fi">Kdenlive-videoprojektitiedosto</comment>
|
||||
<comment xml:lang="fr">Projet vidéo Kdenlive</comment>
|
||||
<comment xml:lang="gl">Documento dun proxecto de vídeo de Kdenlive</comment>
|
||||
@@ -36,6 +38,7 @@
|
||||
</mime-type>
|
||||
<mime-type type="application/x-kdenlivetitle">
|
||||
<comment>Kdenlive video title</comment>
|
||||
<comment xml:lang="ar">عنوان «كدينلايڤ» ڤديوهيّ</comment>
|
||||
<comment xml:lang="bs">Kdenlive video naslov</comment>
|
||||
<comment xml:lang="ca">títol de vídeo del Kdenlive</comment>
|
||||
<comment xml:lang="ca@valencia">títol de vídeo del Kdenlive</comment>
|
||||
@@ -46,6 +49,7 @@
|
||||
<comment xml:lang="en_GB">Kdenlive video title</comment>
|
||||
<comment xml:lang="es">Título de video de Kdenlive</comment>
|
||||
<comment xml:lang="et">Kdenlive'i videotiitel</comment>
|
||||
<comment xml:lang="eu">Kdenlive video izenburua</comment>
|
||||
<comment xml:lang="fi">Kdenlive-video-otsikko</comment>
|
||||
<comment xml:lang="fr">Titre vidéo Kdenlive</comment>
|
||||
<comment xml:lang="gl">Título de vídeo de Kdenlive</comment>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
[KNewStuff2]
|
||||
ProvidersUrl=https://kdenlive.org/data/mltprofilesources.xml
|
||||
TargetDir=kdenlive/profiles
|
||||
Uncompress=archive
|
||||
|
||||
[KNewStuff3]
|
||||
ProvidersUrl=https://kdenlive.org/data/mltprofilesources.xml
|
||||
TargetDir=kdenlive/profiles
|
||||
Uncompress=archive
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
[KNewStuff2]
|
||||
ProvidersUrl=https://kdenlive.org/data/rendersources.xml
|
||||
TargetDir=kdenlive/export
|
||||
Uncompress=archive
|
||||
|
||||
[KNewStuff3]
|
||||
Name=Kdenlive Render Profiles
|
||||
Name[ar]=لاحات «كدينلايڤ» للتّصيير
|
||||
Name[ca]=Perfils de renderització del Kdenlive
|
||||
Name[ca@valencia]=Perfils de renderització del Kdenlive
|
||||
Name[cs]=Profily renderování Kdenlive
|
||||
Name[da]=Kdenlive-renderingsprofiler
|
||||
Name[de]=Kdenlive-Render-Profile
|
||||
Name[el]=Προφίλ αποτύπωσης του Kdenlive
|
||||
Name[en_GB]=Kdenlive Render Profiles
|
||||
Name[es]=Perfiles de procesamiento de Kdenlive
|
||||
Name[fi]=Kdenliven hahmonnusprofiilit
|
||||
Name[fr]=Profils de rendu Kdenlive
|
||||
Name[gl]=Perfís de renderización de Kdenlive
|
||||
Name[it]=Profilo di resa di Kdenlive
|
||||
Name[ko]=Kdenlive 렌더 속성
|
||||
Name[nl]=Renderprofielen van Kdenlive
|
||||
Name[pl]=Profile renderowania Kdenlive
|
||||
Name[pt]=Perfis de Visualização do Kdenlive
|
||||
Name[sk]=Vykresľovacie profily Kdenline
|
||||
Name[sl]=Izrisovalni profili za Kdenlive
|
||||
Name[sv]=Kdenlive-återgivningsprofiler
|
||||
Name[tr]=Kdenlive İşleme Profilleri
|
||||
Name[uk]=Профілі обробки Kdenlive
|
||||
Name[x-test]=xxKdenlive Render Profilesxx
|
||||
Name[zh_CN]=Kdenlive 渲染配置文件
|
||||
ProvidersUrl=http://download.kde.org/ocs/providers.xml
|
||||
Categories=Kdenlive Export Profiles
|
||||
TargetDir=kdenlive/export
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
[KNewStuff2]
|
||||
ProvidersUrl=https://kdenlive.org/data/titletemplates.xml
|
||||
TargetDir=kdenlive/titles
|
||||
Uncompress=archive
|
||||
|
||||
[KNewStuff3]
|
||||
Name=Kdenlive Title Templates
|
||||
Name[ar]=قوالب «كدينلايڤ» للعناوين
|
||||
Name[ca]=Plantilles de títol del Kdenlive
|
||||
Name[ca@valencia]=Plantilles de títol del Kdenlive
|
||||
Name[cs]=Šablony titulků Kdenlive
|
||||
Name[da]=Kdenlive-titelskabeloner
|
||||
Name[de]=Kdenlive-Titelvorlagen
|
||||
Name[el]=Πρότυπα τίτλων του Kdenlive
|
||||
Name[en_GB]=Kdenlive Title Templates
|
||||
Name[es]=Plantillas de título de Kdenlive
|
||||
Name[fi]=Kdenliven otsikkopohjat
|
||||
Name[fr]=Modèles de titre Kdenlive
|
||||
Name[gl]=Modelos de título de Kdenlive
|
||||
Name[it]=Modelli di titolo di Kdenlive
|
||||
Name[ko]=Kdenlive 타이틀 속성
|
||||
Name[nl]=Titelsjablonen van Kdenlive
|
||||
Name[pl]=Szablony tytułów Kdenlive
|
||||
Name[pt]=Perfis de Títulos do Kdenlive
|
||||
Name[sk]=Šablóny dlaždíc Kdenlive
|
||||
Name[sl]=Predloge naslovov za Kdenlive
|
||||
Name[sv]=Kdenlive-titelmallar
|
||||
Name[tr]=Kdenlive Başlık Şablonları
|
||||
Name[uk]=Шаблони титрів Kdenlive
|
||||
Name[x-test]=xxKdenlive Title Templatesxx
|
||||
Name[zh_CN]=Kdenlive 标题模板
|
||||
ProvidersUrl=http://download.kde.org/ocs/providers.xml
|
||||
Categories=Kdenlive Title Templates
|
||||
TargetDir=kdenlive/titles
|
||||
|
||||
@@ -1,18 +1,29 @@
|
||||
[KNewStuff2]
|
||||
ProvidersUrl=http://download.kde.org/khotnewstuff/kdenlive-providers.xml
|
||||
TargetDir=kdenlive/lumas
|
||||
Uncompress=archive
|
||||
|
||||
[KNewStuff3]
|
||||
Name=Kdenlive Transition Wipes
|
||||
Name[ar]=أشرطة «كدينلايڤ» الانتقاليّة
|
||||
Name[ca]=Cortinetes de transició del Kdenlive
|
||||
Name[ca@valencia]=Cortinetes de transició del Kdenlive
|
||||
Name[cs]=Přechod stírání Kdenlive
|
||||
Name[da]=Kdenlive-overgangswipes
|
||||
Name[el]=Μετάβαση με σκούπισμα στο Kdenlive
|
||||
Name[en_GB]=Kdenlive Transition Wipes
|
||||
Name[es]=Barridos de transición de Kdenlive
|
||||
Name[fi]=Kdenliven siirtymäpyyhkäisyt
|
||||
Name[fr]=Transitions par balayage de Kdenlive
|
||||
Name[gl]=Borrados de transición de Kdenlive
|
||||
Name[it]=Wipe di transizione di Kdenlive
|
||||
Name[ko]=Kdenlive 트랜지션 전환
|
||||
Name[nl]=Overgangsvegen van Kdenlive
|
||||
Name[pl]=Przejścia Kdenlive
|
||||
Name[pt]=Varrimentos de Transição do Kdenlive
|
||||
Name[sk]=Zahladenia prechodov Kdenlive
|
||||
Name[sl]=Obrisi prehodov za Kdenlive
|
||||
Name[sv]=Kdenlive-övergångar
|
||||
Name[tr]=Kdenlive Geçiş Ekranları
|
||||
Name[uk]=Перехідні витирання Kdenlive
|
||||
Name[x-test]=xxKdenlive Transition Wipesxx
|
||||
Name[zh_CN]=Kdenlive 过渡擦除
|
||||
ProvidersUrl=http://download.kde.org/ocs/providers.xml
|
||||
Categories=Kdenlive FX
|
||||
TargetDir=kdenlive/lumas
|
||||
TargetDir=kdenlive/lumas/HD
|
||||
Uncompress=archive
|
||||
|
||||
@@ -9,6 +9,7 @@ Item {
|
||||
property string comment
|
||||
property string framenum
|
||||
property rect framesize
|
||||
property rect adjustedFrame
|
||||
property point profile
|
||||
property point center
|
||||
property double zoom
|
||||
@@ -16,6 +17,7 @@ Item {
|
||||
property double scaley
|
||||
property double offsetx : 0
|
||||
property double offsety : 0
|
||||
property double lockratio : -1
|
||||
onScalexChanged: canvas.requestPaint()
|
||||
onScaleyChanged: canvas.requestPaint()
|
||||
onOffsetxChanged: canvas.requestPaint()
|
||||
@@ -224,7 +226,7 @@ Item {
|
||||
color: "transparent"
|
||||
border.color: "#ffff0000"
|
||||
Rectangle {
|
||||
id: "tlhandle"
|
||||
id: tlhandle
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
@@ -240,24 +242,45 @@ Item {
|
||||
anchors.centerIn: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.SizeFDiagCursor
|
||||
onEntered: { tlhandle.color = '#ffff00'}
|
||||
onExited: { tlhandle.color = '#ff0000'}
|
||||
onEntered: {
|
||||
if (!pressed) {
|
||||
tlhandle.color = '#ffff00'
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
if (!pressed) {
|
||||
tlhandle.color = '#ff0000'
|
||||
}
|
||||
}
|
||||
onPressed: {
|
||||
oldMouseX = mouseX
|
||||
oldMouseY = mouseY
|
||||
effectsize.visible = true
|
||||
tlhandle.color = '#ffff00'
|
||||
}
|
||||
onPositionChanged: {
|
||||
if (pressed) {
|
||||
framesize.x = (framerect.x + (mouseX - oldMouseX) - frame.x) / root.scalex;
|
||||
framesize.width = (framerect.width - (mouseX - oldMouseX)) / root.scalex;
|
||||
framesize.y = (framerect.y + (mouseY - oldMouseY) - frame.y) / root.scaley;
|
||||
framesize.height = (framerect.height - (mouseY - oldMouseY)) / root.scaley;
|
||||
if (root.lockratio > 0) {
|
||||
var delta = Math.max(mouseX - oldMouseX, mouseY - oldMouseY)
|
||||
var newwidth = framerect.width - delta
|
||||
adjustedFrame = framesize
|
||||
adjustedFrame.width = Math.round(newwidth / root.scalex);
|
||||
adjustedFrame.height = Math.round(adjustedFrame.width / root.lockratio)
|
||||
adjustedFrame.y = (framerect.y - frame.y) / root.scaley + framesize.height - adjustedFrame.height;
|
||||
adjustedFrame.x = (framerect.x - frame.x) / root.scalex + framesize.width - adjustedFrame.width;
|
||||
framesize = adjustedFrame
|
||||
} else {
|
||||
framesize.x = (framerect.x + (mouseX - oldMouseX) - frame.x) / root.scalex;
|
||||
framesize.width = (framerect.width - (mouseX - oldMouseX)) / root.scalex;
|
||||
framesize.y = (framerect.y + (mouseY - oldMouseY) - frame.y) / root.scaley;
|
||||
framesize.height = (framerect.height - (mouseY - oldMouseY)) / root.scaley;
|
||||
}
|
||||
root.effectChanged()
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
effectsize.visible = false
|
||||
tlhandle.color = '#ff0000'
|
||||
}
|
||||
}
|
||||
Text {
|
||||
@@ -273,7 +296,7 @@ Item {
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: "trhandle"
|
||||
id: trhandle
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
@@ -289,28 +312,48 @@ Item {
|
||||
anchors.centerIn: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.SizeBDiagCursor
|
||||
onEntered: { trhandle.color = '#ffff00'}
|
||||
onExited: { trhandle.color = '#ff0000'}
|
||||
onEntered: {
|
||||
if (!pressed) {
|
||||
trhandle.color = '#ffff00'
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
if (!pressed) {
|
||||
trhandle.color = '#ff0000'
|
||||
}
|
||||
}
|
||||
onPressed: {
|
||||
oldMouseX = mouseX
|
||||
oldMouseY = mouseY
|
||||
effectsize.visible = true
|
||||
trhandle.color = '#ffff00'
|
||||
}
|
||||
onPositionChanged: {
|
||||
if (pressed) {
|
||||
framesize.width = (framerect.width + (mouseX - oldMouseX)) / root.scalex;
|
||||
framesize.y = (framerect.y + (mouseY - oldMouseY) - frame.y) / root.scaley;
|
||||
framesize.height = (framerect.height - (mouseY - oldMouseY)) / root.scaley;
|
||||
if (root.lockratio > 0) {
|
||||
var delta = Math.max(oldMouseX - mouseX, mouseY - oldMouseY)
|
||||
var newwidth = framerect.width - delta
|
||||
adjustedFrame = framesize
|
||||
adjustedFrame.width = Math.round(newwidth / root.scalex);
|
||||
adjustedFrame.height = Math.round(adjustedFrame.width / root.lockratio)
|
||||
adjustedFrame.y = (framerect.y - frame.y) / root.scaley + framesize.height - adjustedFrame.height;
|
||||
framesize = adjustedFrame
|
||||
} else {
|
||||
framesize.width = (framerect.width + (mouseX - oldMouseX)) / root.scalex;
|
||||
framesize.y = (framerect.y + (mouseY - oldMouseY) - frame.y) / root.scaley;
|
||||
framesize.height = (framerect.height - (mouseY - oldMouseY)) / root.scaley;
|
||||
}
|
||||
root.effectChanged()
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
effectsize.visible = false
|
||||
trhandle.color = '#ff0000'
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: "blhandle"
|
||||
id: blhandle
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
@@ -326,28 +369,46 @@ Item {
|
||||
anchors.centerIn: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.SizeBDiagCursor
|
||||
onEntered: { blhandle.color = '#ffff00'}
|
||||
onExited: { blhandle.color = '#ff0000'}
|
||||
onEntered: {
|
||||
if (!pressed) {
|
||||
blhandle.color = '#ffff00'
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
if (!pressed) {
|
||||
blhandle.color = '#ff0000'
|
||||
}
|
||||
}
|
||||
onPressed: {
|
||||
oldMouseX = mouseX
|
||||
oldMouseY = mouseY
|
||||
effectsize.visible = true
|
||||
blhandle.color = '#ffff00'
|
||||
}
|
||||
onPositionChanged: {
|
||||
if (pressed) {
|
||||
framesize.x = (framerect.x + (mouseX - oldMouseX) - frame.x) / root.scalex;
|
||||
framesize.width = (framerect.width - (mouseX - oldMouseX)) / root.scalex;
|
||||
framesize.height = (framerect.height + (mouseY - oldMouseY)) / root.scaley;
|
||||
if (root.lockratio > 0) {
|
||||
var delta = Math.max(mouseX - oldMouseX, oldMouseY - mouseY)
|
||||
var newwidth = framerect.width - delta
|
||||
framesize.x = (framerect.x + (framerect.width - newwidth) - frame.x) / root.scalex;
|
||||
framesize.width = Math.round(newwidth / root.scalex);
|
||||
framesize.height = Math.round(framesize.width / root.lockratio)
|
||||
} else {
|
||||
framesize.x = (framerect.x + (mouseX - oldMouseX) - frame.x) / root.scalex;
|
||||
framesize.width = (framerect.width - (mouseX - oldMouseX)) / root.scalex;
|
||||
framesize.height = (framerect.height + (mouseY - oldMouseY)) / root.scaley;
|
||||
}
|
||||
root.effectChanged()
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
effectsize.visible = false
|
||||
blhandle.color = '#ff0000'
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
id: "brhandle"
|
||||
id: brhandle
|
||||
anchors {
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
@@ -363,22 +424,39 @@ Item {
|
||||
anchors.centerIn: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.SizeFDiagCursor
|
||||
onEntered: { brhandle.color = '#ffff00'}
|
||||
onExited: { brhandle.color = '#ff0000'}
|
||||
onEntered: {
|
||||
if (!pressed) {
|
||||
brhandle.color = '#ffff00'
|
||||
}
|
||||
}
|
||||
onExited: {
|
||||
if (!pressed) {
|
||||
brhandle.color = '#ff0000'
|
||||
}
|
||||
}
|
||||
onPressed: {
|
||||
oldMouseX = mouseX
|
||||
oldMouseY = mouseY
|
||||
effectsize.visible = true
|
||||
brhandle.color = '#ffff00'
|
||||
}
|
||||
onPositionChanged: {
|
||||
if (pressed) {
|
||||
framesize.width = (framerect.width + (mouseX - oldMouseX)) / root.scalex;
|
||||
framesize.height = (framerect.height + (mouseY - oldMouseY)) / root.scaley;
|
||||
if (root.lockratio > 0) {
|
||||
var delta = Math.max(oldMouseX - mouseX, oldMouseY - mouseY)
|
||||
var newwidth = framerect.width - delta
|
||||
framesize.width = Math.round(newwidth / root.scalex);
|
||||
framesize.height = Math.round(framesize.width / root.lockratio)
|
||||
} else {
|
||||
framesize.width = (framerect.width + (mouseX - oldMouseX)) / root.scalex;
|
||||
framesize.height = (framerect.height + (mouseY - oldMouseY)) / root.scaley;
|
||||
}
|
||||
root.effectChanged()
|
||||
}
|
||||
}
|
||||
onReleased: {
|
||||
effectsize.visible = false
|
||||
brhandle.color = '#ff0000'
|
||||
}
|
||||
}
|
||||
Text {
|
||||
|
||||
@@ -46,7 +46,7 @@ End of options
|
||||
.SS
|
||||
.SS KDE options:
|
||||
.TP
|
||||
.B \-\-caption <caption>
|
||||
.B \-\-qwindowtitle <caption>
|
||||
Use 'caption' as name in the titlebar
|
||||
.TP
|
||||
.B \-\-icon <icon>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-2.0+</project_license>
|
||||
<name>Kdenlive</name>
|
||||
<name xml:lang="ar">كدينلايڤ</name>
|
||||
<name xml:lang="ast">Kdenlive</name>
|
||||
<name xml:lang="bs">Kdenlive</name>
|
||||
<name xml:lang="ca">Kdenlive</name>
|
||||
@@ -11,6 +12,7 @@
|
||||
<name xml:lang="cs">Kdenlive</name>
|
||||
<name xml:lang="da">Kdenlive</name>
|
||||
<name xml:lang="de">Kdenlive</name>
|
||||
<name xml:lang="el">Kdenlive</name>
|
||||
<name xml:lang="en-GB">Kdenlive</name>
|
||||
<name xml:lang="es">Kdenlive</name>
|
||||
<name xml:lang="et">Kdenlive</name>
|
||||
@@ -18,6 +20,7 @@
|
||||
<name xml:lang="fr">Kdenlive</name>
|
||||
<name xml:lang="gl">Kdenlive</name>
|
||||
<name xml:lang="it">Kdenlive</name>
|
||||
<name xml:lang="ko">Kdenlive</name>
|
||||
<name xml:lang="nl">Kdenlive</name>
|
||||
<name xml:lang="nn">Kdenlive</name>
|
||||
<name xml:lang="pl">Kdenlive</name>
|
||||
@@ -36,9 +39,10 @@
|
||||
<summary xml:lang="bs">Video uređivač</summary>
|
||||
<summary xml:lang="ca">Editor de vídeo</summary>
|
||||
<summary xml:lang="ca-valencia">Editor de vídeo</summary>
|
||||
<summary xml:lang="cs">Editor videí</summary>
|
||||
<summary xml:lang="cs">Editor videa</summary>
|
||||
<summary xml:lang="da">Videoredigering</summary>
|
||||
<summary xml:lang="de">Video-Editor</summary>
|
||||
<summary xml:lang="el">Επεξεργαστής βίντεο</summary>
|
||||
<summary xml:lang="en-GB">Video Editor</summary>
|
||||
<summary xml:lang="es">Editor de video</summary>
|
||||
<summary xml:lang="et">Videoredaktor</summary>
|
||||
@@ -46,6 +50,7 @@
|
||||
<summary xml:lang="fr">Éditeur vidéo</summary>
|
||||
<summary xml:lang="gl">Editor de vídeo</summary>
|
||||
<summary xml:lang="it">Editor video</summary>
|
||||
<summary xml:lang="ko">동영상 편집기</summary>
|
||||
<summary xml:lang="nl">Videobewerker</summary>
|
||||
<summary xml:lang="nn">Videoredigering</summary>
|
||||
<summary xml:lang="pl">Edytor wideo</summary>
|
||||
@@ -61,16 +66,21 @@
|
||||
<summary xml:lang="zh-TW">影像編輯器</summary>
|
||||
<description>
|
||||
<p>Kdenlive is a non linear video editor. It is based on the MLT framework and accepts many audio and video formats, allows you to add effects, transitions and render into the format of your choice.</p>
|
||||
<p xml:lang="ar">«كدينلايڤ» هو محرّر فيديوهات غير خطّي. بُني على إطار عمل MLT ويقبل العديد من نُسق الصّوت والفيديو. كما ويسمح بإضافة التّأثيرات والانتقالات.</p>
|
||||
<p xml:lang="ca">El Kdenlive és un editor no lineal de vídeo. Està basat en l'entorn de treball MLT i accepta molts formats d'àudio i vídeo, permetent afegir efectes, transicions i representacions en el format de la vostra elecció.</p>
|
||||
<p xml:lang="ca-valencia">El Kdenlive és un editor no lineal de vídeo. Està basat en l'entorn de treball MLT i accepta molts formats d'àudio i vídeo, permetent afegir efectes, transicions i representacions en el format de la vostra elecció.</p>
|
||||
<p xml:lang="cs">Kdenlive je nelineární video editor. Je založený na frameworku MLT a přehrává mnoho zvukových a video formátů, umožňuje přidat efekty, přechody a renderuje do formátu podle vašeho výběru.</p>
|
||||
<p xml:lang="da">Kdenlive er et ikke-lineært videoredigeringsprogram. Det er baseret på MLT-framework og accepterer mange lyd- og videoformater, som giver dig mulighed for at tilføje effekter, overgange og rendere i det format du ønsker.</p>
|
||||
<p xml:lang="de">Kdenlive ist ein Video-Editor für nichtlinearen Schnitt. Es basiert auf MLT und verarbeitet viele Audio- und Video-Formate. Sie können Effekte und Übergänge benutzen und in Formate Ihrer Wahl umwandeln.</p>
|
||||
<p xml:lang="el">Το Kdenlive είναι ένας μη γραμμικός επεξεργαστής βίντεο. Βασίζεται στο πλαίσιο εργασίας MLT και δέχεται πολλούς τύπους ήχου και βίντεο, επιτρέπει την προσθήκη εφέ, μεταβάσεων και αποτύπωσης στον τύπο αποθήκευσης της επιλογής σας.</p>
|
||||
<p xml:lang="en-GB">Kdenlive is a non linear video editor. It is based on the MLT framework and accepts many audio and video formats, allows you to add effects, transitions and render into the format of your choice.</p>
|
||||
<p xml:lang="es">Kdenlive es un editor no lineal de video. Está basado en la infraestructura MLT y acepta numerosos formatos de audio y video, permitiendo agregar efectos, transiciones y procesar el video final en el formato deseado.</p>
|
||||
<p xml:lang="et">Kdenline on mittelineaarne videoredaktor. See tugineb MLT raamistikule ja võimaldab tarvitada paljusid heli- ja videovorminguid, lisada efekte ja üleminekuid ning renderdada tulemuse vajalikku vormingusse.</p>
|
||||
<p xml:lang="fi">Kdenlive on epälineaarinen videoeditori. Se perustuu MLT-frameworkiin ja toimii monen eri ääni- ja videoformaatin kanssa. Voit lisätä efektejä ja siirtymiä, sekä renderöidä projektin haluamaasi tiedostomuotoon.</p>
|
||||
<p xml:lang="fr">Kdenlive est un éditeur vidéo non-linéaire. Il est basé sur le moteur MLT et accèpte de nombreux formats audio et vidéos, permet d'ajouter des effets et transitions, et exporte le rendu dans le format de votre choix.</p>
|
||||
<p xml:lang="fr">Kdenlive est un éditeur vidéo non-linéaire. Il utilise le moteur MLT et accèpte de nombreux formats audio et vidéos, permet d'ajouter des effets et transitions, et exporte le rendu dans le format de votre choix.</p>
|
||||
<p xml:lang="gl">Kdenlive é un editor de vídeo non lineal. Está baseado na infraestrutura MLT e permite moitos formatos de son e vídeo, e permite engadir efectos, engadir transicións, e exportar en calquera formato.</p>
|
||||
<p xml:lang="it">Kdenlive è un editor video non lineare. È basato sull'infrastruttura MLT e accetta numerosi formati audio e video, consente di aggiungere effetti, transizioni e produrre il formato che si desidera.</p>
|
||||
<p xml:lang="ko">Kdenlive는 비선형 동영상 편집기입니다. MLT 프레임워크를 사용하며 여러 음악 및 동영상 형식을 지원하고, 효과 및 트랜지션을 추가할 수 있으며, 원하는 형식으로 렌더링할 수 있습니다.</p>
|
||||
<p xml:lang="nl">Kdenlive is een niet lineaire videobewerker. Het is gebaseerd op het MLT-framework en accepteert vele audio- en video-formaten, biedt de mogelijkheid effecten en overgangen toe te voegen en om te zetten naar het formaat van uw keuze.</p>
|
||||
<p xml:lang="nn">Kdenlive er eit program for ikkje-lineær videoredigering. Det er basert på MLT-rammeverket og støttar mange ulike video- og lydformat. Du kan leggja til spesialeffektar og overgangar, og eksportera til ulike filformat.</p>
|
||||
<p xml:lang="pl">Kdenlive jest nieliniowym edytorem wideo. Oparty jest na szkielecie MLT i może pracować na wielu formatach obrazu i dźwięku, umożliwia dodawanie efektów, przejść i renderowanie ich do dowolnego formatu.</p>
|
||||
@@ -92,6 +102,7 @@
|
||||
<p xml:lang="cs">Vlastnosti:</p>
|
||||
<p xml:lang="da">Funktioner:</p>
|
||||
<p xml:lang="de">Funktionen:</p>
|
||||
<p xml:lang="el">Χαρακτηριστικά:</p>
|
||||
<p xml:lang="en-GB">Features:</p>
|
||||
<p xml:lang="es">Características:</p>
|
||||
<p xml:lang="et">Omadused:</p>
|
||||
@@ -99,6 +110,7 @@
|
||||
<p xml:lang="fr">Fonctionnalités :</p>
|
||||
<p xml:lang="gl">Funcionalidades:</p>
|
||||
<p xml:lang="it">Funzionalità:</p>
|
||||
<p xml:lang="ko">기능:</p>
|
||||
<p xml:lang="nl">Mogelijkheden:</p>
|
||||
<p xml:lang="nn">Funksjonar:</p>
|
||||
<p xml:lang="pl">Możliwości:</p>
|
||||
@@ -114,9 +126,13 @@
|
||||
<p xml:lang="zh-TW">功能:</p>
|
||||
<ul>
|
||||
<li>Intuitive multitrack interface.</li>
|
||||
<li xml:lang="ar">واجهة متعدّدة المسارات بديهيّة.</li>
|
||||
<li xml:lang="ca">Interfície multipista intuïtiva.</li>
|
||||
<li xml:lang="ca-valencia">Interfície multipista intuïtiva.</li>
|
||||
<li xml:lang="cs">Intuitivní vícepohledové rozhraní.</li>
|
||||
<li xml:lang="da">Intuitiv multispor-grænseflade.</li>
|
||||
<li xml:lang="de">Intuitive Mehrspur-Benutzeroberfläche.</li>
|
||||
<li xml:lang="el">Διαισθητική πολυκάναλη διεπαφή.</li>
|
||||
<li xml:lang="en-GB">Intuitive multitrack interface.</li>
|
||||
<li xml:lang="es">Interfaz multipista intuitiva.</li>
|
||||
<li xml:lang="et">Hõlpsasti mõistetav mitme paneeliga liides</li>
|
||||
@@ -124,6 +140,7 @@
|
||||
<li xml:lang="fr">Interface multipiste intuitive.</li>
|
||||
<li xml:lang="gl">Interface intuitiva con varias pistas.</li>
|
||||
<li xml:lang="it">Interfaccia multitraccia intuitiva.</li>
|
||||
<li xml:lang="ko">사용하기 편한 다중 트랙 인터페이스.</li>
|
||||
<li xml:lang="nl">Intuïtief interface met meerdere tracks.</li>
|
||||
<li xml:lang="nn">Intuitivt fleirsporsgrensesnitt.</li>
|
||||
<li xml:lang="pl">Intuicyjny interfejs wielościeżkowy.</li>
|
||||
@@ -141,7 +158,10 @@
|
||||
<li xml:lang="ar">تأثيرات وانتقالات عديدة.</li>
|
||||
<li xml:lang="ca">Molts efectes i transicions.</li>
|
||||
<li xml:lang="ca-valencia">Molts efectes i transicions.</li>
|
||||
<li xml:lang="cs">Spousta efektů a přechodů.</li>
|
||||
<li xml:lang="da">Mange effekter og overgange.</li>
|
||||
<li xml:lang="de">Viele Effekte und Übergänge.</li>
|
||||
<li xml:lang="el">Πολλά εφέ και μεταβάσεις.</li>
|
||||
<li xml:lang="en-GB">Many effects and transitions.</li>
|
||||
<li xml:lang="es">Muchos efectos y transiciones.</li>
|
||||
<li xml:lang="et">Palju efekte ja üleminekuid</li>
|
||||
@@ -149,6 +169,7 @@
|
||||
<li xml:lang="fr">Nombreux effets et transitions.</li>
|
||||
<li xml:lang="gl">Moitos efectos e transicións.</li>
|
||||
<li xml:lang="it">Numerosi effetti e transizioni.</li>
|
||||
<li xml:lang="ko">다양한 효과와 트랜지션.</li>
|
||||
<li xml:lang="nl">Veel effecten en overgangen.</li>
|
||||
<li xml:lang="nn">Mange effektar og overgangar.</li>
|
||||
<li xml:lang="pl">Wiele efektów i przejść.</li>
|
||||
@@ -166,7 +187,10 @@
|
||||
<li xml:lang="ar">نطاقات الألوان</li>
|
||||
<li xml:lang="ca">Àmbits de color</li>
|
||||
<li xml:lang="ca-valencia">Àmbits de color</li>
|
||||
<li xml:lang="cs">Rozsahy barev</li>
|
||||
<li xml:lang="da">Farveskoper</li>
|
||||
<li xml:lang="de">Farbbereiche</li>
|
||||
<li xml:lang="el">Εμβέλειες χρωμάτων</li>
|
||||
<li xml:lang="en-GB">Colour scopes</li>
|
||||
<li xml:lang="es">Indicadores de color</li>
|
||||
<li xml:lang="et">Värviskoobid</li>
|
||||
@@ -174,6 +198,7 @@
|
||||
<li xml:lang="fr">Graphes des couleurs</li>
|
||||
<li xml:lang="gl">Ámbitos de cores.</li>
|
||||
<li xml:lang="it">Diagrammi di colore</li>
|
||||
<li xml:lang="ko">색상 범위</li>
|
||||
<li xml:lang="nl">Kleurreeksen</li>
|
||||
<li xml:lang="nn">Fargeskop</li>
|
||||
<li xml:lang="pl">Zakresy barw</li>
|
||||
@@ -191,7 +216,10 @@
|
||||
<li xml:lang="ar">مُرشد DVD أساسيّ</li>
|
||||
<li xml:lang="ca">Assistent bàsic per als DVD</li>
|
||||
<li xml:lang="ca-valencia">Assistent bàsic per als DVD</li>
|
||||
<li xml:lang="cs">Základní průvodce DVD</li>
|
||||
<li xml:lang="da">Grundlæggende dvd-guide</li>
|
||||
<li xml:lang="de">Einfacher DVD-Assistent</li>
|
||||
<li xml:lang="el">Βασικός οδηγός DVD</li>
|
||||
<li xml:lang="en-GB">Basic DVD Wizard</li>
|
||||
<li xml:lang="es">Asistente básico de DVD</li>
|
||||
<li xml:lang="et">Lihtne DVD nõustaja</li>
|
||||
@@ -199,6 +227,7 @@
|
||||
<li xml:lang="fr">Assistant DVD de base</li>
|
||||
<li xml:lang="gl">Asistente básico para DVD</li>
|
||||
<li xml:lang="it">Procedura guidata di base DVD</li>
|
||||
<li xml:lang="ko">기본 DVD 마법사</li>
|
||||
<li xml:lang="nl">Basis dvd-assistent</li>
|
||||
<li xml:lang="nn">Enkel DVD-vegvisar</li>
|
||||
<li xml:lang="pl">Pomocnik podstawowego DVD</li>
|
||||
@@ -214,12 +243,15 @@
|
||||
<li xml:lang="zh-TW">基本 DVD 精靈</li>
|
||||
</ul>
|
||||
</description>
|
||||
<releases>
|
||||
<release date="2018-01-07" version="17.12.1"/>
|
||||
</releases>
|
||||
<url type="homepage">https://kdenlive.org/</url>
|
||||
<url type="bugtracker">https://bugs.kde.org</url>
|
||||
<url type="help">https://userbase.kde.org/Kdenlive/Manual</url>
|
||||
<screenshots>
|
||||
<screenshot type="source">
|
||||
<image>https://kdenlive.org/wp-content/data/kdenlive-screenshot.png</image>
|
||||
<image>https://cdn.kde.org/screenshots/kdenlive/screenshot-monitors.png</image>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<project_group>KDE</project_group>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# KDE Config File
|
||||
[Desktop Entry]
|
||||
Name=Kdenlive
|
||||
Name[ar]=كدينلايڤ
|
||||
Name[bs]=Kdenlive
|
||||
Name[ca]=Kdenlive
|
||||
Name[ca@valencia]=Kdenlive
|
||||
@@ -19,6 +20,7 @@ Name[hu]=Kdenlive
|
||||
Name[it]=Kdenlive
|
||||
Name[ja]=Kdenlive
|
||||
Name[km]=Kdenlive
|
||||
Name[ko]=Kdenlive
|
||||
Name[lt]=Kdenlive
|
||||
Name[lv]=Kdenlive
|
||||
Name[mr]=के-डि-एनलाइव्ह
|
||||
@@ -45,7 +47,7 @@ GenericName[ar]=محرّر فيديوهات
|
||||
GenericName[bs]=Video uređivač
|
||||
GenericName[ca]=Editor de vídeo
|
||||
GenericName[ca@valencia]=Editor de vídeo
|
||||
GenericName[cs]=Editor videí
|
||||
GenericName[cs]=Editor videa
|
||||
GenericName[da]=Videoredigering
|
||||
GenericName[de]=Video-Editor
|
||||
GenericName[el]=Επεξεργαστής βίντεο
|
||||
@@ -60,6 +62,7 @@ GenericName[hu]=Videoszerkesztő
|
||||
GenericName[it]=Editor video
|
||||
GenericName[ja]=ビデオエディタ
|
||||
GenericName[km]=កម្មវិធីកែសម្រួលវីដេអូ
|
||||
GenericName[ko]=동영상 편집기
|
||||
GenericName[lt]=Video redaktorius
|
||||
GenericName[lv]=Video redaktors
|
||||
GenericName[mr]=व्हिडीओ संपादक
|
||||
@@ -79,45 +82,33 @@ GenericName[uk]=Відеоредактор
|
||||
GenericName[x-test]=xxVideo Editorxx
|
||||
GenericName[zh_CN]=视频编辑器
|
||||
GenericName[zh_TW]=影像編輯器
|
||||
Comment=Nonlinear video editor for KDE
|
||||
Comment[ar]=محرّر فيديوهات غير خطّيّ لكدي
|
||||
Comment[bs]=Nelinearni video uređivač za KDE
|
||||
Comment[ca]=Editor de vídeo no lineal per al KDE
|
||||
Comment[ca@valencia]=Editor de vídeo no lineal per al KDE
|
||||
Comment[cs]=Nelineární editor videí pro KDE
|
||||
Comment[da]=Ikke-lineær videoredigering til KDE
|
||||
Comment[de]=Nichtlinearer Video-Editor für KDE
|
||||
Comment[el]=Μη γραμμικός επεξεργαστής βίντεο για το KDE
|
||||
Comment[en_GB]=Nonlinear video editor for KDE
|
||||
Comment[es]=Editor no lineal de video para KDE
|
||||
Comment[et]=KDE mittelineaarne videoredaktor
|
||||
Comment[fi]=Epälineaarinen videomuokkain KDE:lle
|
||||
Comment[fr]=Éditeur vidéo non linéaire pour KDE
|
||||
Comment[gl]=Editor de vídeo non linear para KDE
|
||||
Comment[hu]=Nemlineáris videoszerkesztő a KDE-hez
|
||||
Comment[it]=Editor di video non lineare per KDE
|
||||
Comment[ja]=KDE 向けノンリニアビデオエディタ
|
||||
Comment[km]=កម្មវិធីកែសម្រួលវីដេអូមិនលីនេអ៊ែរសម្រាប់ KDE
|
||||
Comment[lt]=Nelinijinis veido redaktorius skirtas KDE
|
||||
Comment[lv]=Nelineārais video redaktors KDE videi
|
||||
Comment[mr]=केडीई करिता अरेषीय व्हिडीओ संपादक
|
||||
Comment[nb]=Videoredigeringsprogram for KDE med dataklipping
|
||||
Comment[nl]=Niet-lineaire video-bewerker voor KDE
|
||||
Comment=Nonlinear video editor by KDE
|
||||
Comment[ar]=محرّر فيديوهات غير خطّيّ من كدي
|
||||
Comment[ca]=Editor de vídeo no lineal, creat per la comunitat KDE
|
||||
Comment[ca@valencia]=Editor de vídeo no lineal, creat per la comunitat KDE
|
||||
Comment[cs]=Nelineární editor videa od KDE
|
||||
Comment[da]=Ikke-lineært videoredigeringsprogram af KDE
|
||||
Comment[de]=Nichtlinearer Video-Editor von KDE
|
||||
Comment[el]=Μη γραμμικός επεξεργαστής βίντεο από το KDE
|
||||
Comment[en_GB]=Non-linear video editor by KDE
|
||||
Comment[es]=Editor no lineal de video de KDE
|
||||
Comment[fi]=KDE:n epälineaarinen videomuokkain
|
||||
Comment[fr]=Éditeur vidéo non linéaire par KDE
|
||||
Comment[gl]=Editor de vídeo non linear por KDE
|
||||
Comment[it]=Editor di video non lineare di KDE
|
||||
Comment[ko]=KDE의 비선형 동영상 편집기
|
||||
Comment[nl]=Niet-lineaire video-bewerker door KDE
|
||||
Comment[nn]=Program for ikkje-lineær videoredigering
|
||||
Comment[pl]=Nieliniowy edytor wideo dla KDE
|
||||
Comment[pt]=Editor de vídeo não-linear para o KDE
|
||||
Comment[pt_BR]=Editor de vídeo não-linear para o KDE
|
||||
Comment[ro]=Redactor de imagini neliniar pentru KDE
|
||||
Comment[ru]=Нелинейный видеоредактор от KDE
|
||||
Comment[pl]=Nieliniowy edytor wideo w ramach KDE
|
||||
Comment[pt]=Editor de vídeo não-linear do KDE
|
||||
Comment[pt_BR]=Editor de vídeo não-linear do KDE
|
||||
Comment[sk]=Nelineárny editor videa pre KDE
|
||||
Comment[sl]=Ne-linearni urejevalnik videa za KDE
|
||||
Comment[sv]=Icke-linjär videoeditor för KDE
|
||||
Comment[sl]=Ne-linearni urejevalnik videa s strani KDE
|
||||
Comment[sv]=Icke-linjär videoeditor av KDE
|
||||
Comment[tr]=KDE için doğrusal olmayan video düzenleyici
|
||||
Comment[ug]=KDE ئۈچۈن سىزىقسىز سىن تەھرىرلىگۈچ
|
||||
Comment[uk]=Нелінійний редактор відео для KDE
|
||||
Comment[x-test]=xxNonlinear video editor for KDExx
|
||||
Comment[zh_CN]=KDE 的非线性视频编辑器
|
||||
Comment[zh_TW]=KDE 上的非線性影像編輯器
|
||||
Comment[uk]=Нелінійний редактор відео від KDE
|
||||
Comment[x-test]=xxNonlinear video editor by KDExx
|
||||
Comment[zh_CN]=KDE 推出的非线性视频编辑器
|
||||
Type=Application
|
||||
Exec=kdenlive %U
|
||||
Icon=kdenlive
|
||||
@@ -127,10 +118,13 @@ Terminal=false
|
||||
MimeType=application/x-kdenlive;
|
||||
Categories=Qt;KDE;AudioVideo;AudioVideoEditing;
|
||||
Keywords=editing;video;audio;mlt;kde;
|
||||
Keywords[ar]=تحرير;فيديو;صوت;كدي;واجهة;مسارات;تعدد;
|
||||
Keywords[ca]=edició;vídeo;àudio;mlt;kde;
|
||||
Keywords[ca@valencia]=edició;vídeo;àudio;mlt;kde;
|
||||
Keywords[cs]=úprava;video;zvuk;mlt;kde;
|
||||
Keywords[da]=redigering;video;lyd;mlt;kde;
|
||||
Keywords[de]=Editing;Bearbeitung;Schnitt;Videoschnitt;Video;Audio;MLT;
|
||||
Keywords[el]=επεξεργασία;βίντεο;ήχος;mlt;kde;
|
||||
Keywords[en_GB]=editing;video;audio;mlt;kde;
|
||||
Keywords[es]=edición;video;audio;mlt;kde;
|
||||
Keywords[et]=redigeerimine;muutmine;video;audio;heli;mlt;kde;
|
||||
@@ -138,6 +132,7 @@ Keywords[fi]=editing;video;audio;mlt;kde;editointi;ääni;
|
||||
Keywords[fr]=montage;vidéo;audio;mlt;kde;
|
||||
Keywords[gl]=editing;edición;video;vídeo;audio;son;mlt;kde;
|
||||
Keywords[it]=editing;video;audio;mlt;kde;
|
||||
Keywords[ko]=editing;video;audio;mlt;kde;편집;비디오;오디오;동영상;음악;
|
||||
Keywords[nl]=bewerken;video;audio;mlt;kde;
|
||||
Keywords[nn]=redigering;video;lyd;mlt;kde;
|
||||
Keywords[pl]=edytowanie;video;wideo;filmy;audio;dźwięk;mlt;kde;
|
||||
@@ -146,6 +141,7 @@ Keywords[pt_BR]=edição;vídeo;áudio;mlt;kde;
|
||||
Keywords[sk]=editovanie;video;audio;mlt;kde;
|
||||
Keywords[sl]=urejanje;video;zvok;mlt;kde;
|
||||
Keywords[sv]=redigering;video;ljud;mlt;kde;
|
||||
Keywords[tr]=editing;video;audio;mlt;kde;
|
||||
Keywords[uk]=editing;video;audio;mlt;kde;редагування;відео;звук;аудіо;млт;кдє;
|
||||
Keywords[x-test]=xxeditingxx;xxvideoxx;xxaudioxx;xxmltxx;xxkdexx;
|
||||
Keywords[zh_CN]=editing;video;audio;mlt;kde;编辑;视频;音频;
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
<parameter type="animatedrect" name="rect" default="0 0 %width %height 1">
|
||||
<name>Rectangle</name>
|
||||
</parameter>
|
||||
<parameter type="animated" name="rotation" max="360" min="-360" default="0" notintimeline="1">
|
||||
<name>Rotation</name>
|
||||
</parameter>
|
||||
<parameter type="list" name="compositing" default="0" paramlist="0;11;12;13;14;15;16;17;18;19;20;21;22;23;24;25;26;27;28;29;6;8">
|
||||
<paramlistdisplay>Alpha blend,Xor,Plus,Multiply,Screen,Overlay,Darken,Lighten,Color dodge,Color burn,Hard light,Soft light,Difference,Exclusion,Bitwise or,Bitwise and,Bitwise xor,Bitwise nor,Bitwise nand,Bitwise not xor,Destination in,Destination out</paramlistdisplay>
|
||||
<name>Compositing</name>
|
||||
@@ -13,5 +16,8 @@
|
||||
<parameter type="bool" name="distort" default="0" min="0" max="1">
|
||||
<name>Distort</name>
|
||||
</parameter>
|
||||
<parameter type="bool" name="rotate_center" default="1" min="0" max="1">
|
||||
<name>Rotate from center</name>
|
||||
</parameter>
|
||||
</transition>
|
||||
|
||||
|
||||
@@ -75,13 +75,13 @@ int main(int argc, char **argv)
|
||||
QString srcString = args.takeFirst();
|
||||
QUrl srcurl;
|
||||
if (srcString.startsWith(QLatin1String("consumer:"))) {
|
||||
srcurl = QUrl::fromEncoded(srcString.section(QStringLiteral(":"), 1).toUtf8().constData());
|
||||
srcurl = QUrl::fromEncoded(srcString.section(QLatin1Char(':'), 1).toUtf8().constData());
|
||||
} else {
|
||||
srcurl = QUrl::fromEncoded(srcString.toUtf8().constData());
|
||||
}
|
||||
QString src = srcurl.toLocalFile();
|
||||
// The QUrl path() strips the consumer: protocol, so re-add it if necessary
|
||||
if (srcString.startsWith("consumer:")) {
|
||||
if (srcString.startsWith(QStringLiteral("consumer:"))) {
|
||||
src.prepend(QLatin1String("consumer:"));
|
||||
}
|
||||
QString dest = QFileInfo(QUrl::fromEncoded(args.takeFirst().toUtf8()).toLocalFile()).absoluteFilePath();
|
||||
|
||||
@@ -45,7 +45,7 @@ RenderJob::RenderJob(bool erase, bool usekuiserver, int pid, const QString &rend
|
||||
m_jobUiserver(nullptr),
|
||||
m_kdenliveinterface(nullptr),
|
||||
m_usekuiserver(usekuiserver),
|
||||
m_logfile(dest + ".txt"),
|
||||
m_logfile(dest + QStringLiteral(".txt")),
|
||||
m_erase(erase),
|
||||
m_seconds(0),
|
||||
m_frame(0),
|
||||
|
||||
@@ -15,6 +15,21 @@ else()
|
||||
PURPOSE "")
|
||||
endif()
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic -Wextra")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wcast-qual -Wcast-align -Wfloat-equal -Wpointer-arith")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunreachable-code -Wchar-subscripts -Wcomment -Wformat")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror-implicit-function-declaration -Wmain -Wmissing-braces")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wparentheses -Wsequence-point -Wreturn-type -Wswitch")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wuninitialized -Wreorder -Wundef -Wshadow -Wwrite-strings")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wsign-compare -Wconversion")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wmissing-noreturn -Wsign-conversion -Wunused ")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wstrict-aliasing -Wstrict-overflow -Wconversion")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdisabled-optimization")
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wlogical-op -Wunsafe-loop-optimizations ")
|
||||
endif()
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-parameter -Wshadow -Wno-variadic-macros -Wno-float-conversion")
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
execute_process(
|
||||
COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=mltdatadir mlt-framework
|
||||
@@ -22,7 +37,6 @@ execute_process(
|
||||
RESULT_VARIABLE MLT_DATADIR_failed)
|
||||
if (NOT MLT_DATADIR_failed)
|
||||
string(REGEX REPLACE "[\r\n]" "" MLT_DATADIR "${MLT_DATADIR}")
|
||||
add_definitions(-DMLT_DATADIR=\"${MLT_DATADIR}\")
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
@@ -31,9 +45,11 @@ execute_process(
|
||||
RESULT_VARIABLE MLT_MELTBIN_failed)
|
||||
if (NOT MLT_MELTBIN_failed)
|
||||
string(REGEX REPLACE "[\r\n]" "" MLT_MELTBIN "${MLT_MELTBIN}")
|
||||
add_definitions(-DMLT_MELTBIN=\"${MLT_MELTBIN}\")
|
||||
endif()
|
||||
|
||||
configure_file( mlt_config.h.in ${CMAKE_BINARY_DIR}/generated/mlt_config.h )
|
||||
include_directories( ${CMAKE_BINARY_DIR}/generated/ ) # Make sure it can be included...
|
||||
|
||||
option(WITH_JogShuttle "Build Jog/Shuttle support" ON)
|
||||
|
||||
set(FFMPEG_SUFFIX "" CACHE STRING "FFmpeg custom suffix")
|
||||
@@ -71,6 +87,8 @@ set_package_properties(QtScript PROPERTIES
|
||||
# TRUE
|
||||
# )
|
||||
#endif(APPLE)
|
||||
#add_definitions( -DQT_NO_CAST_FROM_ASCII )
|
||||
#add_definitions( -DQT_NO_CAST_TO_ASCII )
|
||||
|
||||
install(FILES kdenlivesettings.kcfg DESTINATION ${KCFG_INSTALL_DIR})
|
||||
kconfig_add_kcfg_files(kdenlive_SRCS kdenlivesettings.kcfgc)
|
||||
@@ -95,6 +113,7 @@ add_subdirectory(onmonitoritems/rotoscoping)
|
||||
add_subdirectory(mltcontroller)
|
||||
add_subdirectory(bin)
|
||||
add_subdirectory(qml)
|
||||
add_subdirectory(profiles)
|
||||
|
||||
if (Qt5WebKitWidgets_FOUND)
|
||||
add_subdirectory(qt-oauth-lib)
|
||||
@@ -258,7 +277,6 @@ target_link_libraries(kdenlive
|
||||
KF5::Notifications
|
||||
KF5::TextWidgets
|
||||
KF5::IconThemes
|
||||
KF5::Crash
|
||||
Qt5::Svg
|
||||
${OPENGL_LIBRARIES}
|
||||
${OPENGLES_LIBRARIES}
|
||||
@@ -276,6 +294,11 @@ if (KF5_FILEMETADATA)
|
||||
target_link_libraries(kdenlive KF5::FileMetaData)
|
||||
endif()
|
||||
|
||||
if (KF5Crash_FOUND)
|
||||
add_definitions(-DKF5_USE_CRASH)
|
||||
target_link_libraries(kdenlive KF5::Crash)
|
||||
endif()
|
||||
|
||||
qt5_use_modules( kdenlive Script Widgets Concurrent Qml Quick)
|
||||
|
||||
if (Qt5WebKitWidgets_FOUND)
|
||||
@@ -292,9 +315,11 @@ if(Q_WS_X11)
|
||||
target_link_libraries(kdenlive ${X11_LIBRARIES})
|
||||
endif(Q_WS_X11)
|
||||
|
||||
if(SDL_FOUND)
|
||||
if(SDL2_FOUND)
|
||||
target_link_libraries(kdenlive ${SDL2_LIBRARY})
|
||||
elseif(SDL_FOUND)
|
||||
target_link_libraries(kdenlive ${SDL_LIBRARY})
|
||||
endif(SDL_FOUND)
|
||||
endif(SDL2_FOUND)
|
||||
|
||||
if(LIBV4L2_FOUND)
|
||||
include_directories(${LIBV4L2_INCLUDE_DIR})
|
||||
|
||||
@@ -45,7 +45,7 @@ class EqualizerWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EqualizerWidget(QWidget *parent = 0);
|
||||
explicit EqualizerWidget(QWidget *parent = nullptr);
|
||||
|
||||
};
|
||||
|
||||
@@ -53,7 +53,7 @@ class AudioGraphWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AudioGraphWidget(QWidget *parent = 0);
|
||||
explicit AudioGraphWidget(QWidget *parent = nullptr);
|
||||
void drawBackground();
|
||||
|
||||
public slots:
|
||||
@@ -78,7 +78,7 @@ class AudioGraphSpectrum : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
AudioGraphSpectrum(MonitorManager *manager, QWidget *parent = 0);
|
||||
AudioGraphSpectrum(MonitorManager *manager, QWidget *parent = nullptr);
|
||||
virtual ~AudioGraphSpectrum();
|
||||
private:
|
||||
MonitorManager *m_manager;
|
||||
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
* @brief Constructor.
|
||||
* @param parent parent this item should be added to
|
||||
*/
|
||||
AbstractProjectItem(PROJECTITEMTYPE type, const QString &id, AbstractProjectItem *parent = Q_NULLPTR);
|
||||
AbstractProjectItem(PROJECTITEMTYPE type, const QString &id, AbstractProjectItem *parent = nullptr);
|
||||
/**
|
||||
* @brief Creates a project item upon project load.
|
||||
* @param description element for this item.
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
*
|
||||
* We try to read the attributes "name" and "description"
|
||||
*/
|
||||
AbstractProjectItem(PROJECTITEMTYPE type, const QDomElement &description, AbstractProjectItem *parent = Q_NULLPTR);
|
||||
AbstractProjectItem(PROJECTITEMTYPE type, const QDomElement &description, AbstractProjectItem *parent = nullptr);
|
||||
virtual ~AbstractProjectItem();
|
||||
|
||||
bool operator==(const AbstractProjectItem *projectItem) const;
|
||||
|
||||
359
src/bin/bin.cpp
359
src/bin/bin.cpp
@@ -21,6 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "bin.h"
|
||||
#include "kdenlive_debug.h"
|
||||
#include "mainwindow.h"
|
||||
#include "projectitemmodel.h"
|
||||
#include "projectclip.h"
|
||||
@@ -136,7 +137,7 @@ void MyTreeView::editorDestroyed(QObject *editor)
|
||||
|
||||
void MyTreeView::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (isEditing() == true) {
|
||||
if (isEditing()) {
|
||||
QTreeView::keyPressEvent(event);
|
||||
return;
|
||||
}
|
||||
@@ -151,14 +152,14 @@ void MyTreeView::keyPressEvent(QKeyEvent *event)
|
||||
QTreeView::keyPressEvent(event);
|
||||
}
|
||||
|
||||
bool MyTreeView::isEditing()
|
||||
bool MyTreeView::isEditing() const
|
||||
{
|
||||
return m_editing;
|
||||
return state() == QAbstractItemView::EditingState;
|
||||
}
|
||||
|
||||
void MyTreeView::setEditing(bool edit)
|
||||
{
|
||||
m_editing = edit;
|
||||
setState(edit ? QAbstractItemView::EditingState : QAbstractItemView::NoState);
|
||||
}
|
||||
|
||||
bool MyTreeView::performDrag()
|
||||
@@ -175,7 +176,7 @@ bool MyTreeView::performDrag()
|
||||
}
|
||||
QDrag *drag = new QDrag(this);
|
||||
drag->setMimeData(model()->mimeData(indexes));
|
||||
QModelIndex ix = indexes.first();
|
||||
QModelIndex ix = indexes.constFirst();
|
||||
if (ix.isValid()) {
|
||||
QIcon icon = ix.data(AbstractProjectItem::DataThumbnail).value<QIcon>();
|
||||
QPixmap pix = icon.pixmap(iconSize());
|
||||
@@ -301,6 +302,195 @@ void SmallJobLabel::slotSetJobCount(int jobCount)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @class BinItemDelegate
|
||||
* @brief This class is responsible for drawing items in the QTreeView.
|
||||
*/
|
||||
|
||||
class BinItemDelegate: public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit BinItemDelegate(QObject *parent = nullptr): QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
|
||||
{
|
||||
if (index.column() != 0) {
|
||||
return QStyledItemDelegate::updateEditorGeometry(editor, option, index);
|
||||
}
|
||||
QStyleOptionViewItem opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
QRect r1 = option.rect;
|
||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
|
||||
int type = index.data(AbstractProjectItem::ItemTypeRole).toInt();
|
||||
double factor = (double) opt.decorationSize.height() / r1.height();
|
||||
int decoWidth = 2 * textMargin;
|
||||
int mid = 0;
|
||||
if (factor > 0) {
|
||||
decoWidth += opt.decorationSize.width() / factor;
|
||||
}
|
||||
if (type == AbstractProjectItem::ClipItem || type == AbstractProjectItem::SubClipItem) {
|
||||
mid = (int)((r1.height() / 2));
|
||||
}
|
||||
r1.adjust(decoWidth, 0, 0, -mid);
|
||||
QFont ft = option.font;
|
||||
ft.setBold(true);
|
||||
QFontMetricsF fm(ft);
|
||||
QRect r2 = fm.boundingRect(r1, Qt::AlignLeft | Qt::AlignTop, index.data(AbstractProjectItem::DataName).toString()).toRect();
|
||||
editor->setGeometry(r2);
|
||||
}
|
||||
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
|
||||
{
|
||||
QSize hint = QStyledItemDelegate::sizeHint(option, index);
|
||||
QString text = index.data(AbstractProjectItem::DataName).toString();
|
||||
QRectF r = option.rect;
|
||||
QFont ft = option.font;
|
||||
ft.setBold(true);
|
||||
QFontMetricsF fm(ft);
|
||||
QStyle *style = option.widget ? option.widget->style() : QApplication::style();
|
||||
const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
|
||||
int width = fm.boundingRect(r, Qt::AlignLeft | Qt::AlignTop, text).width() + option.decorationSize.width() + 2 * textMargin;
|
||||
hint.setWidth(width);
|
||||
int type = index.data(AbstractProjectItem::ItemTypeRole).toInt();
|
||||
if (type == AbstractProjectItem::FolderItem || type == AbstractProjectItem::FolderUpItem) {
|
||||
return QSize(hint.width(), qMin(option.fontMetrics.lineSpacing() + 4, hint.height()));
|
||||
}
|
||||
if (type == AbstractProjectItem::ClipItem) {
|
||||
return QSize(hint.width(), qMax(option.fontMetrics.lineSpacing() * 2 + 4, qMax(hint.height(), option.decorationSize.height())));
|
||||
}
|
||||
if (type == AbstractProjectItem::SubClipItem) {
|
||||
return QSize(hint.width(), qMax(option.fontMetrics.lineSpacing() * 2 + 4, qMin(hint.height(), (int)(option.decorationSize.height() / 1.5))));
|
||||
}
|
||||
QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
|
||||
QString line1 = index.data(Qt::DisplayRole).toString();
|
||||
QString line2 = index.data(Qt::UserRole).toString();
|
||||
|
||||
int textW = qMax(option.fontMetrics.width(line1), option.fontMetrics.width(line2));
|
||||
QSize iconSize = icon.actualSize(option.decorationSize);
|
||||
return QSize(qMax(textW, iconSize.width()) + 4, option.fontMetrics.lineSpacing() * 2 + 4);
|
||||
}
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
|
||||
{
|
||||
if (index.column() == 0 && !index.data().isNull()) {
|
||||
QRect r1 = option.rect;
|
||||
painter->save();
|
||||
painter->setClipRect(r1);
|
||||
QStyleOptionViewItem opt(option);
|
||||
initStyleOption(&opt, index);
|
||||
int type = index.data(AbstractProjectItem::ItemTypeRole).toInt();
|
||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
|
||||
//QRect r = QStyle::alignedRect(opt.direction, Qt::AlignVCenter | Qt::AlignLeft, opt.decorationSize, r1);
|
||||
|
||||
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
|
||||
if (option.state & QStyle::State_Selected) {
|
||||
painter->setPen(option.palette.highlightedText().color());
|
||||
} else {
|
||||
painter->setPen(option.palette.text().color());
|
||||
}
|
||||
QRect r = r1;
|
||||
QFont font = painter->font();
|
||||
font.setBold(true);
|
||||
painter->setFont(font);
|
||||
if (type == AbstractProjectItem::ClipItem || type == AbstractProjectItem::SubClipItem) {
|
||||
double factor = (double) opt.decorationSize.height() / r1.height();
|
||||
int decoWidth = 2 * textMargin;
|
||||
if (factor > 0) {
|
||||
r.setWidth(opt.decorationSize.width() / factor);
|
||||
// Draw thumbnail
|
||||
opt.icon.paint(painter, r);
|
||||
decoWidth += r.width();
|
||||
}
|
||||
int mid = (int)((r1.height() / 2));
|
||||
r1.adjust(decoWidth, 0, 0, -mid);
|
||||
QRect r2 = option.rect;
|
||||
r2.adjust(decoWidth, mid, 0, 0);
|
||||
QRectF bounding;
|
||||
painter->drawText(r1, Qt::AlignLeft | Qt::AlignTop, index.data(AbstractProjectItem::DataName).toString(), &bounding);
|
||||
font.setBold(false);
|
||||
painter->setFont(font);
|
||||
QString subText = index.data(AbstractProjectItem::DataDuration).toString();
|
||||
if (!subText.isEmpty()) {
|
||||
r2.adjust(0, bounding.bottom() - r2.top(), 0, 0);
|
||||
QColor subTextColor = painter->pen().color();
|
||||
subTextColor.setAlphaF(.5);
|
||||
painter->setPen(subTextColor);
|
||||
painter->drawText(r2, Qt::AlignLeft | Qt::AlignTop, subText, &bounding);
|
||||
// Draw usage counter
|
||||
int usage = index.data(AbstractProjectItem::UsageCount).toInt();
|
||||
if (usage > 0) {
|
||||
bounding.moveLeft(bounding.right() + (2 * textMargin));
|
||||
QString us = QString().sprintf("[%d]", usage);
|
||||
painter->drawText(bounding, Qt::AlignLeft | Qt::AlignTop, us, &bounding);
|
||||
}
|
||||
}
|
||||
if (type == AbstractProjectItem::ClipItem) {
|
||||
// Overlay icon if necessary
|
||||
QVariant v = index.data(AbstractProjectItem::IconOverlay);
|
||||
if (!v.isNull()) {
|
||||
QIcon reload = QIcon::fromTheme(v.toString());
|
||||
r.setTop(r.bottom() - bounding.height());
|
||||
r.setWidth(bounding.height());
|
||||
reload.paint(painter, r);
|
||||
}
|
||||
|
||||
int jobProgress = index.data(AbstractProjectItem::JobProgress).toInt();
|
||||
if (jobProgress > 0 || jobProgress == JobWaiting) {
|
||||
// Draw job progress bar
|
||||
int progressWidth = option.fontMetrics.averageCharWidth() * 8;
|
||||
int progressHeight = option.fontMetrics.ascent() / 4;
|
||||
QRect progress(r1.x() + 1, opt.rect.bottom() - progressHeight - 2, progressWidth, progressHeight);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(Qt::darkGray);
|
||||
if (jobProgress > 0) {
|
||||
painter->drawRoundedRect(progress, 2, 2);
|
||||
painter->setBrush(option.state & QStyle::State_Selected ? option.palette.text() : option.palette.highlight());
|
||||
progress.setWidth((progressWidth - 2) * jobProgress / 100);
|
||||
painter->drawRoundedRect(progress, 2, 2);
|
||||
} else if (jobProgress == JobWaiting) {
|
||||
// Draw kind of a pause icon
|
||||
progress.setWidth(3);
|
||||
painter->drawRect(progress);
|
||||
progress.moveLeft(progress.right() + 3);
|
||||
painter->drawRect(progress);
|
||||
}
|
||||
} else if (jobProgress == JobCrashed) {
|
||||
QString jobText = index.data(AbstractProjectItem::JobMessage).toString();
|
||||
if (!jobText.isEmpty()) {
|
||||
QRectF txtBounding = painter->boundingRect(r2, Qt::AlignRight | Qt::AlignVCenter, " " + jobText + " ");
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(option.palette.highlight());
|
||||
painter->drawRoundedRect(txtBounding, 2, 2);
|
||||
painter->setPen(option.palette.highlightedText().color());
|
||||
painter->drawText(txtBounding, Qt::AlignCenter, jobText);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Folder or Folder Up items
|
||||
double factor = (double) opt.decorationSize.height() / r1.height();
|
||||
int decoWidth = 2 * textMargin;
|
||||
if (factor > 0) {
|
||||
r.setWidth(opt.decorationSize.width() / factor);
|
||||
// Draw thumbnail
|
||||
opt.icon.paint(painter, r);
|
||||
decoWidth += r.width();
|
||||
}
|
||||
r1.adjust(decoWidth, 0, 0, 0);
|
||||
QRectF bounding;
|
||||
painter->drawText(r1, Qt::AlignLeft | Qt::AlignTop, index.data(AbstractProjectItem::DataName).toString(), &bounding);
|
||||
}
|
||||
painter->restore();
|
||||
} else {
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LineEventEater::LineEventEater(QObject *parent) : QObject(parent)
|
||||
{
|
||||
}
|
||||
@@ -421,10 +611,16 @@ Bin::Bin(QWidget *parent) :
|
||||
disableEffects->setChecked(false);
|
||||
pCore->window()->actionCollection()->addAction(QStringLiteral("disable_bin_effects"), disableEffects);
|
||||
|
||||
m_renameFolderAction = new QAction(i18n("Rename Folder"), this);
|
||||
connect(m_renameFolderAction, &QAction::triggered, this, &Bin::slotRenameFolder);
|
||||
m_renameFolderAction->setData("rename_folder");
|
||||
pCore->window()->actionCollection()->addAction(QStringLiteral("rename_folder"), m_renameFolderAction);
|
||||
#if KXMLGUI_VERSION_MINOR > 24 || KXMLGUI_VERSION_MAJOR > 5
|
||||
m_renameAction = KStandardAction::renameFile(this, SLOT(slotRenameItem()), this);
|
||||
m_renameAction->setText(i18n("Rename"));
|
||||
#else
|
||||
m_renameAction = new QAction(i18n("Rename"), this);
|
||||
connect(m_renameAction, &QAction::triggered, this, &Bin::slotRenameItem);
|
||||
m_renameAction->setShortcut(Qt::Key_F2);
|
||||
#endif
|
||||
m_renameAction->setData("rename");
|
||||
pCore->window()->actionCollection()->addAction(QStringLiteral("rename"), m_renameAction);
|
||||
|
||||
listType->setToolBarMode(KSelectAction::MenuMode);
|
||||
connect(listType, SIGNAL(triggered(QAction *)), this, SLOT(slotInitView(QAction *)));
|
||||
@@ -740,7 +936,7 @@ const QStringList Bin::getFolderInfo(const QModelIndex &selectedIx)
|
||||
folderInfo << QString();
|
||||
return folderInfo;
|
||||
}
|
||||
QModelIndex ix = indexes.first();
|
||||
QModelIndex ix = indexes.constFirst();
|
||||
if (ix.isValid() && (m_proxyModel->selectionModel()->isSelected(ix) || selectedIx.isValid())) {
|
||||
AbstractProjectItem *currentItem = static_cast<AbstractProjectItem *>(m_proxyModel->mapToSource(ix).internalPointer());
|
||||
while (currentItem->itemType() != AbstractProjectItem::FolderItem) {
|
||||
@@ -791,11 +987,11 @@ void Bin::deleteClip(const QString &id)
|
||||
|
||||
ProjectClip *Bin::getFirstSelectedClip()
|
||||
{
|
||||
QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
const QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
if (indexes.isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
foreach (const QModelIndex &ix, indexes) {
|
||||
for (const QModelIndex &ix : indexes) {
|
||||
AbstractProjectItem *item = static_cast<AbstractProjectItem *>(m_proxyModel->mapToSource(ix).internalPointer());
|
||||
ProjectClip *clip = qobject_cast<ProjectClip *>(item);
|
||||
if (clip) {
|
||||
@@ -807,15 +1003,15 @@ ProjectClip *Bin::getFirstSelectedClip()
|
||||
|
||||
void Bin::slotDeleteClip()
|
||||
{
|
||||
QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
QStringList clipIds;
|
||||
QStringList subClipIds;
|
||||
QStringList foldersIds;
|
||||
ProjectSubClip *sub;
|
||||
ProjectSubClip *sub = nullptr;
|
||||
QPoint zone;
|
||||
bool usedFolder = false;
|
||||
// check folders, remove child folders if there is any
|
||||
QList<ProjectFolder *> topFolders;
|
||||
const QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
foreach (const QModelIndex &ix, indexes) {
|
||||
if (!ix.isValid() || ix.column() != 0) {
|
||||
continue;
|
||||
@@ -828,7 +1024,7 @@ void Bin::slotDeleteClip()
|
||||
QString subId = item->clipId();
|
||||
sub = static_cast<ProjectSubClip *>(item);
|
||||
zone = sub->zone();
|
||||
subId.append(":" + QString::number(zone.x()) + ":" + QString::number(zone.y()));
|
||||
subId.append(QLatin1Char(':') + QString::number(zone.x()) + QLatin1Char(':') + QString::number(zone.y()));
|
||||
subClipIds << subId;
|
||||
continue;
|
||||
}
|
||||
@@ -909,8 +1105,8 @@ void Bin::slotDeleteClip()
|
||||
|
||||
void Bin::slotReloadClip()
|
||||
{
|
||||
QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
foreach (const QModelIndex &ix, indexes) {
|
||||
const QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
for (const QModelIndex &ix : indexes) {
|
||||
if (!ix.isValid() || ix.column() != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -955,8 +1151,8 @@ void Bin::slotReloadClip()
|
||||
|
||||
void Bin::slotLocateClip()
|
||||
{
|
||||
QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
foreach (const QModelIndex &ix, indexes) {
|
||||
const QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
for (const QModelIndex &ix : indexes) {
|
||||
if (!ix.isValid() || ix.column() != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -970,7 +1166,7 @@ void Bin::slotLocateClip()
|
||||
qCDebug(KDENLIVE_LOG) << " / / " + url.toString();
|
||||
} else {
|
||||
if(!exists) {
|
||||
emitMessage(i18n("Couldn't locate ") + QString(" (" + url.toString() + ")"), 100, ErrorMessage);
|
||||
emitMessage(i18n("Couldn't locate ") + QString(" (" + url.toString() + QLatin1Char(')')), 100, ErrorMessage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -980,8 +1176,8 @@ void Bin::slotLocateClip()
|
||||
|
||||
void Bin::slotDuplicateClip()
|
||||
{
|
||||
QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
foreach (const QModelIndex &ix, indexes) {
|
||||
const QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
for (const QModelIndex &ix : indexes) {
|
||||
if (!ix.isValid() || ix.column() != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -1020,7 +1216,7 @@ void Bin::setMonitor(Monitor *monitor)
|
||||
connect(m_monitor, SIGNAL(addClipToProject(QUrl)), this, SLOT(slotAddClipToProject(QUrl)));
|
||||
connect(m_monitor, SIGNAL(requestAudioThumb(QString)), this, SLOT(slotSendAudioThumb(QString)));
|
||||
connect(m_monitor, &Monitor::refreshCurrentClip, this, &Bin::slotOpenCurrent);
|
||||
connect(m_monitor, SIGNAL(updateClipMarker(QString, QList<CommentedTime>)), this, SLOT(slotAddClipMarker(QString, QList<CommentedTime>)));
|
||||
connect(m_monitor, SIGNAL(updateClipMarker(QString,QList<CommentedTime>)), this, SLOT(slotAddClipMarker(QString,QList<CommentedTime>)));
|
||||
connect(this, &Bin::openClip, m_monitor, &Monitor::slotOpenClip);
|
||||
}
|
||||
|
||||
@@ -1092,8 +1288,7 @@ void Bin::setDocument(KdenliveDoc *project)
|
||||
|
||||
void Bin::slotAddUrl(const QString &url, int folderId, const QMap<QString, QString> &data)
|
||||
{
|
||||
QList<QUrl>urls;
|
||||
urls << QUrl::fromLocalFile(url);
|
||||
const QList<QUrl> urls = QList<QUrl>() << QUrl::fromLocalFile(url);
|
||||
QStringList folderInfo;
|
||||
if (folderId >= 0) {
|
||||
QModelIndex ix = getIndexForId(QString::number(folderId), true);
|
||||
@@ -1108,9 +1303,8 @@ void Bin::slotAddUrl(const QString &url, int folderId, const QMap<QString, QStri
|
||||
|
||||
void Bin::slotAddUrl(const QString &url, const QMap<QString, QString> &data)
|
||||
{
|
||||
QList<QUrl>urls;
|
||||
urls << QUrl::fromLocalFile(url);
|
||||
QStringList folderInfo = getFolderInfo();
|
||||
const QList<QUrl> urls = QList<QUrl>() << QUrl::fromLocalFile(url);
|
||||
const QStringList folderInfo = getFolderInfo();
|
||||
ClipCreationDialog::createClipsCommand(m_doc, urls, folderInfo, this, data);
|
||||
}
|
||||
|
||||
@@ -1183,7 +1377,6 @@ QString Bin::slotAddFolder(const QString &folderName)
|
||||
if (id.isValid() && id2.isValid()) {
|
||||
m_proxyModel->selectionModel()->select(QItemSelection(m_proxyModel->mapFromSource(id), m_proxyModel->mapFromSource(id2)), QItemSelectionModel::Select);
|
||||
}
|
||||
m_itemView->setProperty("editing", true);
|
||||
m_itemView->edit(m_proxyModel->mapFromSource(ix));
|
||||
}
|
||||
return newId;
|
||||
@@ -1316,7 +1509,7 @@ void Bin::removeFolder(const QString &id, QUndoCommand *deleteCommand)
|
||||
// Check parent item
|
||||
ProjectFolder *folder = m_rootFolder->folder(id);
|
||||
AbstractProjectItem *parent = folder->parent();
|
||||
if (folder->count() > 0) {
|
||||
if (!folder->isEmpty()) {
|
||||
// Folder has clips inside, warn user
|
||||
if (KMessageBox::warningContinueCancel(this, i18np("Folder contains a clip, delete anyways ?", "Folder contains %1 clips, delete anyways ?", folder->count())) != KMessageBox::Continue) {
|
||||
return;
|
||||
@@ -1502,9 +1695,9 @@ void Bin::autoSelect()
|
||||
QList<ProjectClip *> Bin::selectedClips()
|
||||
{
|
||||
//TODO: handle clips inside folders
|
||||
QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
const QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
QList<ProjectClip *> list;
|
||||
foreach (const QModelIndex &ix, indexes) {
|
||||
for (const QModelIndex &ix : indexes) {
|
||||
if (!ix.isValid() || ix.column() != 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -1706,7 +1899,6 @@ void Bin::contextMenuEvent(QContextMenuEvent *event)
|
||||
m_editAction->setVisible(!isFolder);
|
||||
m_clipsActionsMenu->setEnabled(enableClipActions);
|
||||
m_extractAudioAction->setEnabled(enableClipActions);
|
||||
m_renameFolderAction->setVisible(isFolder);
|
||||
m_openAction->setVisible(!isFolder);
|
||||
m_reloadAction->setVisible(!isFolder);
|
||||
m_duplicateAction->setVisible(!isFolder);
|
||||
@@ -1720,6 +1912,7 @@ void Bin::contextMenuEvent(QContextMenuEvent *event)
|
||||
m_locateAction->setVisible(!isFolder && (isImported));
|
||||
|
||||
// Show menu
|
||||
event->setAccepted(true);
|
||||
if (enableClipActions) {
|
||||
m_menu->exec(event->globalPos());
|
||||
} else {
|
||||
@@ -1761,7 +1954,6 @@ void Bin::slotItemDoubleClicked(const QModelIndex &ix, const QPoint pos)
|
||||
IconRect.setSize(m_itemView->iconSize());
|
||||
if (!pos.isNull() && ((ix.column() == 2 && item->itemType() == AbstractProjectItem::ClipItem) || !IconRect.contains(pos))) {
|
||||
// User clicked outside icon, trigger rename
|
||||
m_itemView->setProperty("editing", true);
|
||||
m_itemView->edit(ix);
|
||||
return;
|
||||
}
|
||||
@@ -1877,7 +2069,7 @@ void Bin::showClipProperties(ProjectClip *clip, bool forceRefresh)
|
||||
connect(this, &Bin::refreshPanelMarkers, panel, &ClipPropertiesController::slotFillMarkers);
|
||||
connect(panel, SIGNAL(updateClipProperties(QString, QMap<QString, QString>, QMap<QString, QString>)), this, SLOT(slotEditClipCommand(QString, QMap<QString, QString>, QMap<QString, QString>)));
|
||||
connect(panel, SIGNAL(seekToFrame(int)), m_monitor, SLOT(slotSeek(int)));
|
||||
connect(panel, SIGNAL(addMarkers(QString, QList<CommentedTime>)), this, SLOT(slotAddClipMarker(QString, QList<CommentedTime>)));
|
||||
connect(panel, SIGNAL(addMarkers(QString,QList<CommentedTime>)), this, SLOT(slotAddClipMarker(QString,QList<CommentedTime>)));
|
||||
connect(panel, &ClipPropertiesController::editClip, this, &Bin::slotEditClip);
|
||||
connect(panel, SIGNAL(editAnalysis(QString, QString, QString)), this, SLOT(slotAddClipExtraData(QString, QString, QString)));
|
||||
|
||||
@@ -1913,7 +2105,7 @@ void Bin::slotThumbnailReady(const QString &id, const QImage &img, bool fromFile
|
||||
// Save thumbnail for later reuse
|
||||
bool ok = false;
|
||||
if (!fromFile) {
|
||||
img.save(m_doc->getCacheDir(CacheThumbs, &ok).absoluteFilePath(clip->hash() + ".png"));
|
||||
img.save(m_doc->getCacheDir(CacheThumbs, &ok).absoluteFilePath(clip->hash() + QStringLiteral(".png")));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2130,7 +2322,7 @@ void Bin::setupGeneratorMenu()
|
||||
}
|
||||
m_menu->addAction(m_editAction);
|
||||
m_menu->addAction(m_openAction);
|
||||
m_menu->addAction(m_renameFolderAction);
|
||||
m_menu->addAction(m_renameAction);
|
||||
m_menu->addAction(m_deleteAction);
|
||||
m_menu->insertSeparator(m_deleteAction);
|
||||
}
|
||||
@@ -2324,11 +2516,10 @@ void Bin::slotStartCutJob(const QString &id)
|
||||
|
||||
void Bin::startJob(const QString &id, AbstractClipJob::JOBTYPE type)
|
||||
{
|
||||
QList<ProjectClip *> clips;
|
||||
ProjectClip *clip = getBinClip(id);
|
||||
if (clip && !hasPendingJob(id, type)) {
|
||||
// Launch job
|
||||
clips << clip;
|
||||
const QList<ProjectClip *> clips = {clip};
|
||||
m_jobManager->prepareJobs(clips, m_doc->fps(), type);
|
||||
}
|
||||
}
|
||||
@@ -2426,7 +2617,7 @@ void Bin::slotEffectDropped(QString id, QDomElement effect)
|
||||
m_doc->commandStack()->push(command);
|
||||
}
|
||||
|
||||
void Bin::slotUpdateEffect(QString id, QDomElement oldEffect, QDomElement newEffect, int ix)
|
||||
void Bin::slotUpdateEffect(QString id, QDomElement oldEffect, QDomElement newEffect, int ix, bool refreshStack, bool updateClip)
|
||||
{
|
||||
if (id.isEmpty()) {
|
||||
id = m_monitor->activeClipId();
|
||||
@@ -2434,7 +2625,7 @@ void Bin::slotUpdateEffect(QString id, QDomElement oldEffect, QDomElement newEff
|
||||
if (id.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
UpdateBinEffectCommand *command = new UpdateBinEffectCommand(this, id, oldEffect, newEffect, ix);
|
||||
UpdateBinEffectCommand *command = new UpdateBinEffectCommand(this, id, oldEffect, newEffect, ix, refreshStack, updateClip);
|
||||
m_doc->commandStack()->push(command);
|
||||
}
|
||||
|
||||
@@ -2537,14 +2728,16 @@ void Bin::addEffect(const QString &id, QDomElement &effect)
|
||||
m_monitor->refreshMonitorIfActive();
|
||||
}
|
||||
|
||||
void Bin::updateEffect(const QString &id, QDomElement &effect, int ix, bool refreshStackWidget)
|
||||
void Bin::updateEffect(const QString &id, QDomElement &effect, int ix, bool refreshStackWidget, bool updateClip)
|
||||
{
|
||||
ProjectClip *currentItem = m_rootFolder->clip(id);
|
||||
if (!currentItem) {
|
||||
return;
|
||||
}
|
||||
currentItem->updateEffect(m_monitor->profileInfo(), effect, ix, refreshStackWidget);
|
||||
m_monitor->refreshMonitorIfActive();
|
||||
currentItem->updateEffect(m_monitor->profileInfo(), effect, ix, refreshStackWidget, updateClip);
|
||||
if (updateClip) {
|
||||
m_monitor->refreshMonitorIfActive();
|
||||
}
|
||||
}
|
||||
|
||||
void Bin::changeEffectState(const QString &id, const QList<int> &indexes, bool disable, bool refreshStack)
|
||||
@@ -2617,7 +2810,7 @@ void Bin::droppedUrls(const QList<QUrl> &urls, const QStringList &folderInfo)
|
||||
current = m_proxyModel->mapToSource(m_proxyModel->selectionModel()->currentIndex());
|
||||
} else {
|
||||
// get index for folder
|
||||
current = getIndexForId(folderInfo.first(), true);
|
||||
current = getIndexForId(folderInfo.constFirst(), true);
|
||||
}
|
||||
slotItemDropped(urls, current);
|
||||
}
|
||||
@@ -2653,9 +2846,10 @@ void Bin::slotItemDropped(const QList<QUrl> &urls, const QModelIndex &parent)
|
||||
// user dropped a folder, import its files
|
||||
clipsToAdd.removeAll(file);
|
||||
QDir dir(file.toLocalFile());
|
||||
QStringList result = dir.entryList(QDir::Files);
|
||||
const QStringList result = dir.entryList(QDir::Files);
|
||||
QList<QUrl> folderFiles;
|
||||
foreach (const QString &path, result) {
|
||||
folderFiles.reserve(result.count());
|
||||
for (const QString &path : result) {
|
||||
folderFiles.append(QUrl::fromLocalFile(dir.absoluteFilePath(path)));
|
||||
}
|
||||
if (!folderFiles.isEmpty()) {
|
||||
@@ -2676,7 +2870,6 @@ void Bin::slotItemDropped(const QList<QUrl> &urls, const QModelIndex &parent)
|
||||
|
||||
void Bin::slotExpandUrl(const ItemInfo &info, const QString &url, QUndoCommand *command)
|
||||
{
|
||||
QStringList folderInfo;
|
||||
// Create folder to hold imported clips
|
||||
QString folderName = QFileInfo(url).fileName().section(QLatin1Char('.'), 0, 0);
|
||||
QString folderId = QString::number(getFreeFolderId());
|
||||
@@ -2734,18 +2927,20 @@ void Bin::slotExpandUrl(const ItemInfo &info, const QString &url, QUndoCommand *
|
||||
QString hash;
|
||||
QString mltService = EffectsList::property(prod, QStringLiteral("mlt_service"));
|
||||
if (mltService == QLatin1String("pixbuf")
|
||||
|| mltService == QLatin1String("qimage")
|
||||
|| mltService == QLatin1String("kdenlivetitle")
|
||||
|| mltService == QLatin1String("color")
|
||||
|| mltService == QLatin1String("colour")) {
|
||||
hash = mltService + QStringLiteral(":")
|
||||
+ EffectsList::property(prod, QStringLiteral("kdenlive:clipname")) + QStringLiteral(":")
|
||||
+ EffectsList::property(prod, QStringLiteral("kdenlive:folderid")) + QStringLiteral(":");
|
||||
hash = mltService + QLatin1Char(':')
|
||||
+ EffectsList::property(prod, QStringLiteral("kdenlive:clipname")) + QLatin1Char(':')
|
||||
+ EffectsList::property(prod, QStringLiteral("kdenlive:folderid")) + QLatin1Char(':');
|
||||
if (mltService == QLatin1String("kdenlivetitle")) {
|
||||
// Calculate hash based on title contents.
|
||||
hash.append(QString(QCryptographicHash::hash(EffectsList::property(prod, QStringLiteral("xmldata")).toUtf8(),
|
||||
QCryptographicHash::Md5
|
||||
).toHex()));
|
||||
} else if (mltService == QLatin1String("pixbuf")
|
||||
|| mltService == QLatin1String("qimage")
|
||||
|| mltService == QLatin1String("color")
|
||||
|| mltService == QLatin1String("colour")) {
|
||||
hash.append(EffectsList::property(prod, QStringLiteral("resource")));
|
||||
@@ -2833,7 +3028,7 @@ void Bin::renameSubClip(const QString &id, const QString &newName, const QString
|
||||
}
|
||||
sub->setName(newName);
|
||||
clip->setProducerProperty("kdenlive:clipzone." + oldName, QString());
|
||||
clip->setProducerProperty("kdenlive:clipzone." + newName, QString::number(in) + ";" + QString::number(out));
|
||||
clip->setProducerProperty("kdenlive:clipzone." + newName, QString::number(in) + QLatin1Char(';') + QString::number(out));
|
||||
emit itemUpdated(sub);
|
||||
}
|
||||
|
||||
@@ -3067,7 +3262,7 @@ void Bin::slotGotFilterJobResults(const QString &id, int startPos, int track, co
|
||||
EffectsList::setParameter(newEffect, i.key(), i.value());
|
||||
++i;
|
||||
}
|
||||
ctl->updateEffect(pCore->monitorManager()->projectMonitor()->profileInfo(), newEffect, effect.attribute(QStringLiteral("kdenlive_ix")).toInt());
|
||||
ctl->updateEffect(pCore->monitorManager()->projectMonitor()->profileInfo(), newEffect, effect.attribute(QStringLiteral("kdenlive_ix")).toInt(), true);
|
||||
emit masterClipUpdated(ctl, m_monitor);
|
||||
// TODO use undo / redo for bin clip edit effect
|
||||
/*EditEffectCommand *command = new EditEffectCommand(this, clip->track(), clip->startPos(), effect, newEffect, clip->selectedEffectIndex(), true, true);
|
||||
@@ -3101,7 +3296,7 @@ void Bin::slotGotFilterJobResults(const QString &id, int startPos, int track, co
|
||||
QString label = filterInfo.value(QStringLiteral("label"));
|
||||
QString key = filterInfo.value(QStringLiteral("key"));
|
||||
int offset = filterInfo.value(QStringLiteral("offset")).toInt();
|
||||
QStringList value = results.value(key).split(';', QString::SkipEmptyParts);
|
||||
QStringList value = results.value(key).split(QLatin1Char(';'), QString::SkipEmptyParts);
|
||||
//qCDebug(KDENLIVE_LOG)<<"// RESULT; "<<key<<" = "<<value;
|
||||
if (filterInfo.contains(QStringLiteral("resultmessage"))) {
|
||||
QString mess = filterInfo.value(QStringLiteral("resultmessage"));
|
||||
@@ -3161,7 +3356,7 @@ void Bin::slotGotFilterJobResults(const QString &id, int startPos, int track, co
|
||||
if (!pos.contains(QLatin1Char('='))) {
|
||||
continue;
|
||||
}
|
||||
int newPos = pos.section('=', 0, 0).toInt();
|
||||
int newPos = pos.section(QLatin1Char('='), 0, 0).toInt();
|
||||
// Don't use scenes shorter than 1 second
|
||||
if (newPos - cutPos < 24) {
|
||||
continue;
|
||||
@@ -3207,7 +3402,7 @@ void Bin::slotLoadClipMarkers(const QString &id)
|
||||
}
|
||||
cbox->setCurrentIndex(KdenliveSettings::default_marker_type());
|
||||
//TODO KF5 how to add custom cbox to Qfiledialog
|
||||
QPointer<QFileDialog> fd = new QFileDialog(this, i18n("Load Clip Markers"), m_doc->projectDataFolder());
|
||||
QScopedPointer<QFileDialog> fd(new QFileDialog(this, i18n("Load Clip Markers"), m_doc->projectDataFolder()));
|
||||
fd->setMimeTypeFilters(QStringList() << QStringLiteral("text/plain"));
|
||||
fd->setFileMode(QFileDialog::ExistingFile);
|
||||
if (fd->exec() != QDialog::Accepted) {
|
||||
@@ -3216,9 +3411,8 @@ void Bin::slotLoadClipMarkers(const QString &id)
|
||||
QStringList selection = fd->selectedFiles();
|
||||
QString url;
|
||||
if (!selection.isEmpty()) {
|
||||
url = selection.first();
|
||||
url = selection.constFirst();
|
||||
}
|
||||
delete fd;
|
||||
|
||||
//QUrl url = KFileDialog::getOpenUrl(QUrl("kfiledialog:///projectfolder"), "text/plain", this, i18n("Load marker file"));
|
||||
if (url.isEmpty()) {
|
||||
@@ -3242,7 +3436,7 @@ void Bin::slotLoadClipMarkers(const QString &id)
|
||||
QList<CommentedTime> markersList;
|
||||
foreach (const QString &line, lines) {
|
||||
markerText.clear();
|
||||
values = line.split('\t', QString::SkipEmptyParts);
|
||||
values = line.split(QLatin1Char('\t'), QString::SkipEmptyParts);
|
||||
double time1 = values.at(0).toDouble(&ok);
|
||||
double time2 = -1;
|
||||
if (!ok) {
|
||||
@@ -3300,7 +3494,7 @@ void Bin::slotSaveClipMarkers(const QString &id)
|
||||
}
|
||||
cbox->setCurrentIndex(0);
|
||||
//TODO KF5 how to add custom cbox to Qfiledialog
|
||||
QPointer<QFileDialog> fd = new QFileDialog(this, i18n("Save Clip Markers"), m_doc->projectDataFolder());
|
||||
QScopedPointer<QFileDialog> fd(new QFileDialog(this, i18n("Save Clip Markers"), m_doc->projectDataFolder()));
|
||||
fd->setMimeTypeFilters(QStringList() << QStringLiteral("text/plain"));
|
||||
fd->setFileMode(QFileDialog::AnyFile);
|
||||
fd->setAcceptMode(QFileDialog::AcceptSave);
|
||||
@@ -3310,9 +3504,8 @@ void Bin::slotSaveClipMarkers(const QString &id)
|
||||
QStringList selection = fd->selectedFiles();
|
||||
QString url;
|
||||
if (!selection.isEmpty()) {
|
||||
url = selection.first();
|
||||
url = selection.constFirst();
|
||||
}
|
||||
delete fd;
|
||||
//QString url = KFileDialog::getSaveFileName(QUrl("kfiledialog:///projectfolder"), "text/plain", this, i18n("Save markers"));
|
||||
if (url.isEmpty()) {
|
||||
return;
|
||||
@@ -3384,8 +3577,11 @@ void Bin::deleteAllClipMarkers(const QString &id)
|
||||
}
|
||||
}
|
||||
|
||||
void Bin::slotGetCurrentProjectImage(bool request)
|
||||
void Bin::slotGetCurrentProjectImage(const QString &clipId, bool request)
|
||||
{
|
||||
if (!clipId.isEmpty()) {
|
||||
(pCore->projectManager()->currentTimeline()->hideClip(clipId, request));
|
||||
}
|
||||
pCore->monitorManager()->projectMonitor()->slotGetCurrentImage(request);
|
||||
}
|
||||
|
||||
@@ -3396,7 +3592,7 @@ void Bin::showTitleWidget(ProjectClip *clip)
|
||||
QDir titleFolder(m_doc->projectDataFolder() + QStringLiteral("/titles"));
|
||||
titleFolder.mkpath(QStringLiteral("."));
|
||||
TitleWidget dia_ui(QUrl(), m_doc->timecode(), titleFolder.absolutePath(), pCore->monitorManager()->projectMonitor()->render, pCore->window());
|
||||
connect(&dia_ui, &TitleWidget::requestBackgroundFrame, pCore->monitorManager()->projectMonitor(), &Monitor::slotGetCurrentImage);
|
||||
connect(&dia_ui, &TitleWidget::requestBackgroundFrame, this, &Bin::slotGetCurrentProjectImage);
|
||||
QDomDocument doc;
|
||||
QString xmldata = clip->getProducerProperty(QStringLiteral("xmldata"));
|
||||
if (xmldata.isEmpty() && QFile::exists(path)) {
|
||||
@@ -3406,7 +3602,7 @@ void Bin::showTitleWidget(ProjectClip *clip)
|
||||
} else {
|
||||
doc.setContent(xmldata);
|
||||
}
|
||||
dia_ui.setXml(doc);
|
||||
dia_ui.setXml(doc, clip->clipId());
|
||||
if (dia_ui.exec() == QDialog::Accepted) {
|
||||
QMap<QString, QString> newprops;
|
||||
newprops.insert(QStringLiteral("xmldata"), dia_ui.xml().toString());
|
||||
@@ -3497,8 +3693,8 @@ void Bin::slotQueryRemoval(const QString &id, const QString &url, const QString
|
||||
m_invalidClipDialog->addClip(id, url);
|
||||
int result = m_invalidClipDialog->exec();
|
||||
if (result == QDialog::Accepted) {
|
||||
QStringList ids = m_invalidClipDialog->getIds();
|
||||
foreach (const QString &i, ids) {
|
||||
const QStringList ids = m_invalidClipDialog->getIds();
|
||||
for (const QString &i : ids) {
|
||||
deleteClip(i);
|
||||
}
|
||||
}
|
||||
@@ -3549,7 +3745,7 @@ void Bin::updateTimelineProducers(const QString &id, const QMap<QString, QString
|
||||
void Bin::showSlideshowWidget(ProjectClip *clip)
|
||||
{
|
||||
QString folder = QFileInfo(clip->url()).absolutePath();
|
||||
qDebug()<<" ** * CLIP ABS PATH: "<<clip->url()<<" = "<<folder;
|
||||
qCDebug(KDENLIVE_LOG)<<" ** * CLIP ABS PATH: "<<clip->url()<<" = "<<folder;
|
||||
SlideshowClip *dia = new SlideshowClip(m_doc->timecode(), folder, clip, this);
|
||||
if (dia->exec() == QDialog::Accepted) {
|
||||
// edit clip properties
|
||||
@@ -3580,6 +3776,7 @@ void Bin::showSlideshowWidget(ProjectClip *clip)
|
||||
oldProperties.insert(QStringLiteral("animation"), clip->getProducerProperty(QStringLiteral("animation")));
|
||||
slotEditClipCommand(clip->clipId(), oldProperties, properties);
|
||||
}
|
||||
delete dia;
|
||||
}
|
||||
|
||||
void Bin::slotDisableEffects(bool disable)
|
||||
@@ -3603,20 +3800,16 @@ void Bin::setBinEffectsDisabledStatus(bool disabled)
|
||||
pCore->projectManager()->disableBinEffects(disabled);
|
||||
}
|
||||
|
||||
void Bin::slotRenameFolder()
|
||||
void Bin::slotRenameItem()
|
||||
{
|
||||
QModelIndexList indexes = m_proxyModel->selectionModel()->selectedIndexes();
|
||||
foreach (const QModelIndex &ix, indexes) {
|
||||
if (!ix.isValid() || ix.column() != 0) {
|
||||
const QModelIndexList indexes = m_proxyModel->selectionModel()->selectedRows(0);
|
||||
for (const QModelIndex &ix : indexes) {
|
||||
if (!ix.isValid()) {
|
||||
continue;
|
||||
}
|
||||
AbstractProjectItem *item = static_cast<AbstractProjectItem *>(m_proxyModel->mapToSource(ix).internalPointer());
|
||||
ProjectFolder *currentItem = qobject_cast<ProjectFolder *>(item);
|
||||
if (currentItem) {
|
||||
m_itemView->setProperty("editing", true);
|
||||
m_itemView->edit(ix);
|
||||
return;
|
||||
}
|
||||
m_itemView->setCurrentIndex(ix);
|
||||
m_itemView->edit(ix);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3719,8 +3912,8 @@ void Bin::slotMessageActionTriggered()
|
||||
|
||||
void Bin::resetUsageCount()
|
||||
{
|
||||
QList<ProjectClip *> clipList = m_rootFolder->childClips();
|
||||
foreach (ProjectClip *clip, clipList) {
|
||||
const QList<ProjectClip *> clipList = m_rootFolder->childClips();
|
||||
for (ProjectClip *clip : clipList) {
|
||||
clip->setRefCount(0);
|
||||
}
|
||||
}
|
||||
@@ -3776,7 +3969,7 @@ QDir Bin::getCacheDir(CacheType type, bool *ok) const
|
||||
|
||||
bool Bin::addClip(QDomElement elem, const QString &clipId)
|
||||
{
|
||||
const QString producerId = clipId.section('_', 0, 0);
|
||||
const QString producerId = clipId.section(QLatin1Char('_'), 0, 0);
|
||||
elem.setAttribute(QStringLiteral("id"), producerId);
|
||||
if ((KdenliveSettings::default_profile().isEmpty() || KdenliveSettings::checkfirstprojectclip()) && isEmpty()) {
|
||||
elem.setAttribute(QStringLiteral("checkProfile"), 1);
|
||||
@@ -3818,7 +4011,7 @@ void Bin::saveZone(const QStringList &info, const QDir &dir)
|
||||
if (info.size() != 3) {
|
||||
return;
|
||||
}
|
||||
ProjectClip *clip = getBinClip(info.first());
|
||||
ProjectClip *clip = getBinClip(info.constFirst());
|
||||
if (clip && clip->controller()) {
|
||||
QPoint zone(info.at(1).toInt(), info.at(2).toInt());
|
||||
clip->controller()->saveZone(zone, dir);
|
||||
|
||||
235
src/bin/bin.h
235
src/bin/bin.h
@@ -60,17 +60,20 @@ class ProjectSortProxyModel;
|
||||
class JobManager;
|
||||
class ProjectFolderUp;
|
||||
class InvalidDialog;
|
||||
class BinItemDelegate;
|
||||
class BinMessageWidget;
|
||||
class SmallJobLabel;
|
||||
|
||||
namespace Mlt
|
||||
{
|
||||
class Producer;
|
||||
};
|
||||
}
|
||||
|
||||
class MyListView: public QListView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MyListView(QWidget *parent = Q_NULLPTR);
|
||||
explicit MyListView(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE;
|
||||
@@ -83,7 +86,7 @@ class MyTreeView: public QTreeView
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool editing READ isEditing WRITE setEditing)
|
||||
public:
|
||||
explicit MyTreeView(QWidget *parent = Q_NULLPTR);
|
||||
explicit MyTreeView(QWidget *parent = nullptr);
|
||||
void setEditing(bool edit);
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
@@ -99,7 +102,7 @@ private:
|
||||
QPoint m_startPos;
|
||||
bool m_editing;
|
||||
bool performDrag();
|
||||
bool isEditing();
|
||||
bool isEditing() const;
|
||||
|
||||
signals:
|
||||
void focusView();
|
||||
@@ -109,8 +112,8 @@ class BinMessageWidget: public KMessageWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit BinMessageWidget(QWidget *parent = Q_NULLPTR);
|
||||
BinMessageWidget(const QString &text, QWidget *parent = Q_NULLPTR);
|
||||
explicit BinMessageWidget(QWidget *parent = nullptr);
|
||||
BinMessageWidget(const QString &text, QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool event(QEvent *ev) Q_DECL_OVERRIDE;
|
||||
@@ -123,7 +126,7 @@ class SmallJobLabel: public QPushButton
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SmallJobLabel(QWidget *parent = Q_NULLPTR);
|
||||
explicit SmallJobLabel(QWidget *parent = nullptr);
|
||||
static const QString getStyleSheet(const QPalette &p);
|
||||
void setAction(QAction *action);
|
||||
private:
|
||||
@@ -144,200 +147,11 @@ private slots:
|
||||
void slotTimeLineFinished();
|
||||
};
|
||||
|
||||
/**
|
||||
* @class BinItemDelegate
|
||||
* @brief This class is responsible for drawing items in the QTreeView.
|
||||
*/
|
||||
|
||||
class BinItemDelegate: public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
explicit BinItemDelegate(QObject *parent = Q_NULLPTR): QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
|
||||
{
|
||||
if (index.column() != 0) {
|
||||
return QStyledItemDelegate::updateEditorGeometry(editor, option, index);
|
||||
}
|
||||
QStyleOptionViewItem opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
QRect r1 = option.rect;
|
||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
|
||||
int type = index.data(AbstractProjectItem::ItemTypeRole).toInt();
|
||||
double factor = (double) opt.decorationSize.height() / r1.height();
|
||||
int decoWidth = 2 * textMargin;
|
||||
int mid = 0;
|
||||
if (factor != 0) {
|
||||
decoWidth += opt.decorationSize.width() / factor;
|
||||
}
|
||||
if (type == AbstractProjectItem::ClipItem || type == AbstractProjectItem::SubClipItem) {
|
||||
mid = (int)((r1.height() / 2));
|
||||
}
|
||||
r1.adjust(decoWidth, 0, 0, -mid);
|
||||
QFont ft = option.font;
|
||||
ft.setBold(true);
|
||||
QFontMetricsF fm(ft);
|
||||
QRect r2 = fm.boundingRect(r1, Qt::AlignLeft | Qt::AlignTop, index.data(AbstractProjectItem::DataName).toString()).toRect();
|
||||
editor->setGeometry(r2);
|
||||
}
|
||||
|
||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
|
||||
{
|
||||
QSize hint = QStyledItemDelegate::sizeHint(option, index);
|
||||
QString text = index.data(AbstractProjectItem::DataName).toString();
|
||||
QRectF r = option.rect;
|
||||
QFont ft = option.font;
|
||||
ft.setBold(true);
|
||||
QFontMetricsF fm(ft);
|
||||
QStyle *style = option.widget ? option.widget->style() : QApplication::style();
|
||||
const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
|
||||
int width = fm.boundingRect(r, Qt::AlignLeft | Qt::AlignTop, text).width() + option.decorationSize.width() + 2 * textMargin;
|
||||
hint.setWidth(width);
|
||||
int type = index.data(AbstractProjectItem::ItemTypeRole).toInt();
|
||||
if (type == AbstractProjectItem::FolderItem || type == AbstractProjectItem::FolderUpItem) {
|
||||
return QSize(hint.width(), qMin(option.fontMetrics.lineSpacing() + 4, hint.height()));
|
||||
}
|
||||
if (type == AbstractProjectItem::ClipItem) {
|
||||
return QSize(hint.width(), qMax(option.fontMetrics.lineSpacing() * 2 + 4, qMax(hint.height(), option.decorationSize.height())));
|
||||
}
|
||||
if (type == AbstractProjectItem::SubClipItem) {
|
||||
return QSize(hint.width(), qMax(option.fontMetrics.lineSpacing() * 2 + 4, qMin(hint.height(), (int)(option.decorationSize.height() / 1.5))));
|
||||
}
|
||||
QIcon icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
|
||||
QString line1 = index.data(Qt::DisplayRole).toString();
|
||||
QString line2 = index.data(Qt::UserRole).toString();
|
||||
|
||||
int textW = qMax(option.fontMetrics.width(line1), option.fontMetrics.width(line2));
|
||||
QSize iconSize = icon.actualSize(option.decorationSize);
|
||||
return QSize(qMax(textW, iconSize.width()) + 4, option.fontMetrics.lineSpacing() * 2 + 4);
|
||||
}
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const Q_DECL_OVERRIDE
|
||||
{
|
||||
if (index.column() == 0 && !index.data().isNull()) {
|
||||
QRect r1 = option.rect;
|
||||
painter->save();
|
||||
painter->setClipRect(r1);
|
||||
QStyleOptionViewItem opt(option);
|
||||
initStyleOption(&opt, index);
|
||||
int type = index.data(AbstractProjectItem::ItemTypeRole).toInt();
|
||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
const int textMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin) + 1;
|
||||
//QRect r = QStyle::alignedRect(opt.direction, Qt::AlignVCenter | Qt::AlignLeft, opt.decorationSize, r1);
|
||||
|
||||
style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
|
||||
if (option.state & QStyle::State_Selected) {
|
||||
painter->setPen(option.palette.highlightedText().color());
|
||||
} else {
|
||||
painter->setPen(option.palette.text().color());
|
||||
}
|
||||
QRect r = r1;
|
||||
QFont font = painter->font();
|
||||
font.setBold(true);
|
||||
painter->setFont(font);
|
||||
if (type == AbstractProjectItem::ClipItem || type == AbstractProjectItem::SubClipItem) {
|
||||
double factor = (double) opt.decorationSize.height() / r1.height();
|
||||
int decoWidth = 2 * textMargin;
|
||||
if (factor != 0) {
|
||||
r.setWidth(opt.decorationSize.width() / factor);
|
||||
// Draw thumbnail
|
||||
opt.icon.paint(painter, r);
|
||||
decoWidth += r.width();
|
||||
}
|
||||
int mid = (int)((r1.height() / 2));
|
||||
r1.adjust(decoWidth, 0, 0, -mid);
|
||||
QRect r2 = option.rect;
|
||||
r2.adjust(decoWidth, mid, 0, 0);
|
||||
QRectF bounding;
|
||||
painter->drawText(r1, Qt::AlignLeft | Qt::AlignTop, index.data(AbstractProjectItem::DataName).toString(), &bounding);
|
||||
font.setBold(false);
|
||||
painter->setFont(font);
|
||||
QString subText = index.data(AbstractProjectItem::DataDuration).toString();
|
||||
if (!subText.isEmpty()) {
|
||||
r2.adjust(0, bounding.bottom() - r2.top(), 0, 0);
|
||||
QColor subTextColor = painter->pen().color();
|
||||
subTextColor.setAlphaF(.5);
|
||||
painter->setPen(subTextColor);
|
||||
painter->drawText(r2, Qt::AlignLeft | Qt::AlignTop, subText, &bounding);
|
||||
// Draw usage counter
|
||||
int usage = index.data(AbstractProjectItem::UsageCount).toInt();
|
||||
if (usage > 0) {
|
||||
bounding.moveLeft(bounding.right() + (2 * textMargin));
|
||||
QString us = QString().sprintf("[%d]", usage);
|
||||
painter->drawText(bounding, Qt::AlignLeft | Qt::AlignTop, us, &bounding);
|
||||
}
|
||||
}
|
||||
if (type == AbstractProjectItem::ClipItem) {
|
||||
// Overlay icon if necessary
|
||||
QVariant v = index.data(AbstractProjectItem::IconOverlay);
|
||||
if (!v.isNull()) {
|
||||
QIcon reload = QIcon::fromTheme(v.toString());
|
||||
r.setTop(r.bottom() - bounding.height());
|
||||
r.setWidth(bounding.height());
|
||||
reload.paint(painter, r);
|
||||
}
|
||||
|
||||
int jobProgress = index.data(AbstractProjectItem::JobProgress).toInt();
|
||||
if (jobProgress > 0 || jobProgress == JobWaiting) {
|
||||
// Draw job progress bar
|
||||
int progressWidth = option.fontMetrics.averageCharWidth() * 8;
|
||||
int progressHeight = option.fontMetrics.ascent() / 4;
|
||||
QRect progress(r1.x() + 1, opt.rect.bottom() - progressHeight - 2, progressWidth, progressHeight);
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(Qt::darkGray);
|
||||
if (jobProgress > 0) {
|
||||
painter->drawRoundedRect(progress, 2, 2);
|
||||
painter->setBrush(option.state & QStyle::State_Selected ? option.palette.text() : option.palette.highlight());
|
||||
progress.setWidth((progressWidth - 2) * jobProgress / 100);
|
||||
painter->drawRoundedRect(progress, 2, 2);
|
||||
} else if (jobProgress == JobWaiting) {
|
||||
// Draw kind of a pause icon
|
||||
progress.setWidth(3);
|
||||
painter->drawRect(progress);
|
||||
progress.moveLeft(progress.right() + 3);
|
||||
painter->drawRect(progress);
|
||||
}
|
||||
} else if (jobProgress == JobCrashed) {
|
||||
QString jobText = index.data(AbstractProjectItem::JobMessage).toString();
|
||||
if (!jobText.isEmpty()) {
|
||||
QRectF txtBounding = painter->boundingRect(r2, Qt::AlignRight | Qt::AlignVCenter, " " + jobText + " ");
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->setBrush(option.palette.highlight());
|
||||
painter->drawRoundedRect(txtBounding, 2, 2);
|
||||
painter->setPen(option.palette.highlightedText().color());
|
||||
painter->drawText(txtBounding, Qt::AlignCenter, jobText);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Folder or Folder Up items
|
||||
double factor = (double) opt.decorationSize.height() / r1.height();
|
||||
int decoWidth = 2 * textMargin;
|
||||
if (factor != 0) {
|
||||
r.setWidth(opt.decorationSize.width() / factor);
|
||||
// Draw thumbnail
|
||||
opt.icon.paint(painter, r);
|
||||
decoWidth += r.width();
|
||||
}
|
||||
r1.adjust(decoWidth, 0, 0, 0);
|
||||
QRectF bounding;
|
||||
painter->drawText(r1, Qt::AlignLeft | Qt::AlignTop, index.data(AbstractProjectItem::DataName).toString(), &bounding);
|
||||
}
|
||||
painter->restore();
|
||||
} else {
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class LineEventEater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit LineEventEater(QObject *parent = Q_NULLPTR);
|
||||
explicit LineEventEater(QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
|
||||
@@ -347,6 +161,7 @@ signals:
|
||||
void showClearButton(bool);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @class Bin
|
||||
* @brief The bin widget takes care of both item model and view upon project opening.
|
||||
@@ -360,7 +175,7 @@ class Bin : public QWidget
|
||||
enum BinViewType {BinTreeView, BinIconView };
|
||||
|
||||
public:
|
||||
explicit Bin(QWidget *parent = Q_NULLPTR);
|
||||
explicit Bin(QWidget *parent = nullptr);
|
||||
~Bin();
|
||||
|
||||
bool isLoading;
|
||||
@@ -486,7 +301,7 @@ public:
|
||||
/** @brief Add an effect to a bin clip. */
|
||||
void addEffect(const QString &id, QDomElement &effect);
|
||||
/** @brief Update a bin clip effect. */
|
||||
void updateEffect(const QString &id, QDomElement &effect, int ix, bool refreshStackWidget);
|
||||
void updateEffect(const QString &id, QDomElement &effect, int ix, bool refreshStackWidget, bool updateClip);
|
||||
void changeEffectState(const QString &id, const QList<int> &indexes, bool disable, bool refreshStack);
|
||||
/** @brief Edit an effect settings to a bin clip. */
|
||||
void editMasterEffect(ClipController *ctl);
|
||||
@@ -541,7 +356,7 @@ private slots:
|
||||
void slotShowDescColumn(bool show);
|
||||
|
||||
/** @brief Setup the bin view type (icon view, tree view, ...).
|
||||
* @param action The action whose data defines the view type or Q_NULLPTR to keep default view */
|
||||
* @param action The action whose data defines the view type or nullptr to keep default view */
|
||||
void slotInitView(QAction *action);
|
||||
|
||||
/** @brief Update status for clip jobs */
|
||||
@@ -555,11 +370,12 @@ private slots:
|
||||
void slotItemDropped(const QStringList &ids, const QModelIndex &parent);
|
||||
void slotItemDropped(const QList<QUrl> &urls, const QModelIndex &parent);
|
||||
void slotEffectDropped(const QString &effect, const QModelIndex &parent);
|
||||
void slotUpdateEffect(QString id, QDomElement oldEffect, QDomElement newEffect, int ix);
|
||||
void slotUpdateEffect(QString id, QDomElement oldEffect, QDomElement newEffect, int ix, bool refreshStack = false, bool updateClip = true);
|
||||
void slotChangeEffectState(QString id, const QList<int> &indexes, bool disable);
|
||||
void slotItemEdited(const QModelIndex &, const QModelIndex &, const QVector<int> &);
|
||||
void slotAddUrl(const QString &url, int folderId, const QMap<QString, QString> &data = QMap<QString, QString>());
|
||||
void slotAddUrl(const QString &url, const QMap<QString, QString> &data = QMap<QString, QString>());
|
||||
|
||||
void slotPrepareJobsMenu();
|
||||
void slotShowJobLog();
|
||||
/** @brief process clip job result. */
|
||||
@@ -575,8 +391,8 @@ private slots:
|
||||
void slotGotFocus();
|
||||
/** @brief Dis/Enable all bin effects. */
|
||||
void slotDisableEffects(bool disable);
|
||||
/** @brief Rename a Bin Folder. */
|
||||
void slotRenameFolder();
|
||||
/** @brief Rename a Bin Item. */
|
||||
void slotRenameItem();
|
||||
void slotCreateAudioThumbs();
|
||||
void doRefreshPanel(const QString &id);
|
||||
/** @brief Send audio thumb data to monitor for display. */
|
||||
@@ -622,7 +438,7 @@ public slots:
|
||||
void slotAddClipCut(const QString &id, int in, int out);
|
||||
/** @brief Open current clip in an external editing application */
|
||||
void slotOpenClip();
|
||||
void slotAddClipMarker(const QString &id, const QList<CommentedTime> &newMarker, QUndoCommand *groupCommand = Q_NULLPTR);
|
||||
void slotAddClipMarker(const QString &id, const QList<CommentedTime> &newMarker, QUndoCommand *groupCommand = nullptr);
|
||||
void slotLoadClipMarkers(const QString &id);
|
||||
void slotSaveClipMarkers(const QString &id);
|
||||
void slotDuplicateClip();
|
||||
@@ -634,14 +450,17 @@ public slots:
|
||||
/** @brief Abort audio thumbnail for clip with id */
|
||||
void slotAbortAudioThumb(const QString &id, long duration);
|
||||
/** @brief Add extra data to a clip. */
|
||||
void slotAddClipExtraData(const QString &id, const QString &key, const QString &data = QString(), QUndoCommand *groupCommand = Q_NULLPTR);
|
||||
void slotAddClipExtraData(const QString &id, const QString &key, const QString &data = QString(), QUndoCommand *groupCommand = nullptr);
|
||||
void slotUpdateClipProperties(const QString &id, const QMap<QString, QString> &properties, bool refreshPropertiesPanel);
|
||||
/** @brief Pass some important properties to timeline track producers. */
|
||||
void updateTimelineProducers(const QString &id, const QMap<QString, QString> &passProperties);
|
||||
/** @brief Add effect to active Bin clip (used when double clicking an effect in list). */
|
||||
void slotEffectDropped(QString id, QDomElement);
|
||||
/** @brief Request current frame from project monitor. */
|
||||
void slotGetCurrentProjectImage(bool request);
|
||||
/** @brief Request current frame from project monitor.
|
||||
* @param clipId is the id of a clip we want to hide from screenshot
|
||||
* @param request true to start capture process, false to end it. It is necessary to emit a false after image is received
|
||||
**/
|
||||
void slotGetCurrentProjectImage(const QString &clipId, bool request);
|
||||
void slotExpandUrl(const ItemInfo &info, const QString &url, QUndoCommand *command);
|
||||
void abortAudioThumbs();
|
||||
/** @brief Abort all ongoing operations to prepare close. */
|
||||
@@ -702,7 +521,7 @@ private:
|
||||
QAction *m_locateAction;
|
||||
QAction *m_proxyAction;
|
||||
QAction *m_deleteAction;
|
||||
QAction *m_renameFolderAction;
|
||||
QAction *m_renameAction;
|
||||
QMenu *m_jobsMenu;
|
||||
QAction *m_cancelJobs;
|
||||
QAction *m_discardCurrentClipJobs;
|
||||
|
||||
@@ -154,26 +154,27 @@ void RemoveBinEffectCommand::redo()
|
||||
m_bin->removeEffect(m_clipId, m_effect);
|
||||
}
|
||||
|
||||
UpdateBinEffectCommand::UpdateBinEffectCommand(Bin *bin, const QString &clipId, QDomElement &oldEffect, QDomElement &newEffect, int ix, QUndoCommand *parent) :
|
||||
UpdateBinEffectCommand::UpdateBinEffectCommand(Bin *bin, const QString &clipId, QDomElement &oldEffect, QDomElement &newEffect, int ix, bool refreshStack, bool updateClip, QUndoCommand *parent) :
|
||||
QUndoCommand(parent),
|
||||
m_bin(bin),
|
||||
m_clipId(clipId),
|
||||
m_oldEffect(oldEffect),
|
||||
m_newEffect(newEffect),
|
||||
m_ix(ix),
|
||||
m_refreshStack(false)
|
||||
m_refreshStack(refreshStack),
|
||||
m_updateClip(updateClip)
|
||||
{
|
||||
setText(i18n("Edit Bin Effect"));
|
||||
}
|
||||
// virtual
|
||||
void UpdateBinEffectCommand::undo()
|
||||
{
|
||||
m_bin->updateEffect(m_clipId, m_oldEffect, m_ix, m_refreshStack);
|
||||
m_bin->updateEffect(m_clipId, m_oldEffect, m_ix, m_refreshStack, m_updateClip);
|
||||
}
|
||||
// virtual
|
||||
void UpdateBinEffectCommand::redo()
|
||||
{
|
||||
m_bin->updateEffect(m_clipId, m_newEffect, m_ix, m_refreshStack);
|
||||
m_bin->updateEffect(m_clipId, m_newEffect, m_ix, m_refreshStack, m_updateClip);
|
||||
m_refreshStack = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ class Bin;
|
||||
class AddBinFolderCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit AddBinFolderCommand(Bin *bin, const QString &id, const QString &name, const QString &parentId, bool remove = false, QUndoCommand *parent = Q_NULLPTR);
|
||||
explicit AddBinFolderCommand(Bin *bin, const QString &id, const QString &name, const QString &parentId, bool remove = false, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -43,7 +43,7 @@ private:
|
||||
class MoveBinClipCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit MoveBinClipCommand(Bin *bin, const QString &clipId, const QString &oldParentId, const QString &newParentId, QUndoCommand *parent = Q_NULLPTR);
|
||||
explicit MoveBinClipCommand(Bin *bin, const QString &clipId, const QString &oldParentId, const QString &newParentId, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -56,7 +56,7 @@ private:
|
||||
class MoveBinFolderCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit MoveBinFolderCommand(Bin *bin, const QString &clipId, const QString &oldParentId, const QString &newParentId, QUndoCommand *parent = Q_NULLPTR);
|
||||
explicit MoveBinFolderCommand(Bin *bin, const QString &clipId, const QString &oldParentId, const QString &newParentId, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -69,7 +69,7 @@ private:
|
||||
class RenameBinFolderCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit RenameBinFolderCommand(Bin *bin, const QString &folderId, const QString &newName, const QString &oldName, QUndoCommand *parent = Q_NULLPTR);
|
||||
explicit RenameBinFolderCommand(Bin *bin, const QString &folderId, const QString &newName, const QString &oldName, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -82,7 +82,7 @@ private:
|
||||
class AddBinEffectCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit AddBinEffectCommand(Bin *bin, const QString &clipId, QDomElement &effect, QUndoCommand *parent = Q_NULLPTR);
|
||||
explicit AddBinEffectCommand(Bin *bin, const QString &clipId, QDomElement &effect, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -94,7 +94,7 @@ private:
|
||||
class RemoveBinEffectCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit RemoveBinEffectCommand(Bin *bin, const QString &clipId, QDomElement &effect, QUndoCommand *parent = Q_NULLPTR);
|
||||
explicit RemoveBinEffectCommand(Bin *bin, const QString &clipId, QDomElement &effect, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -106,7 +106,7 @@ private:
|
||||
class UpdateBinEffectCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit UpdateBinEffectCommand(Bin *bin, const QString &clipId, QDomElement &oldEffect, QDomElement &newEffect, int ix, QUndoCommand *parent = Q_NULLPTR);
|
||||
explicit UpdateBinEffectCommand(Bin *bin, const QString &clipId, QDomElement &oldEffect, QDomElement &newEffect, int ix, bool refreshStack, bool updateClip, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -116,12 +116,13 @@ private:
|
||||
QDomElement m_newEffect;
|
||||
int m_ix;
|
||||
bool m_refreshStack;
|
||||
bool m_updateClip;
|
||||
};
|
||||
|
||||
class ChangeMasterEffectStateCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
ChangeMasterEffectStateCommand(Bin *bin, const QString &clipId, const QList<int> &effectIndexes, bool disable, QUndoCommand *parent = Q_NULLPTR);
|
||||
ChangeMasterEffectStateCommand(Bin *bin, const QString &clipId, const QList<int> &effectIndexes, bool disable, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -135,7 +136,7 @@ private:
|
||||
class MoveBinEffectCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit MoveBinEffectCommand(Bin *bin, const QString &clipId, const QList<int> &oldPos, int newPos, QUndoCommand *parent = Q_NULLPTR);
|
||||
explicit MoveBinEffectCommand(Bin *bin, const QString &clipId, const QList<int> &oldPos, int newPos, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -148,7 +149,7 @@ private:
|
||||
class RenameBinSubClipCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit RenameBinSubClipCommand(Bin *bin, const QString &clipId, const QString &newName, const QString &oldName, int in, int out, QUndoCommand *parent = Q_NULLPTR);
|
||||
explicit RenameBinSubClipCommand(Bin *bin, const QString &clipId, const QString &newName, const QString &oldName, int in, int out, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -163,7 +164,7 @@ private:
|
||||
class AddBinClipCutCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
explicit AddBinClipCutCommand(Bin *bin, const QString &clipId, int in, int out, bool add, QUndoCommand *parent = Q_NULLPTR);
|
||||
explicit AddBinClipCutCommand(Bin *bin, const QString &clipId, int in, int out, bool add, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -177,7 +178,7 @@ private:
|
||||
class EditClipCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
EditClipCommand(Bin *bin, const QString &id, const QMap<QString, QString> &oldparams, const QMap<QString, QString> &newparams, bool doIt, QUndoCommand *parent = Q_NULLPTR);
|
||||
EditClipCommand(Bin *bin, const QString &id, const QMap<QString, QString> &oldparams, const QMap<QString, QString> &newparams, bool doIt, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
@@ -196,7 +197,7 @@ private:
|
||||
class AddClipCommand : public QUndoCommand
|
||||
{
|
||||
public:
|
||||
AddClipCommand(Bin *bin, const QDomElement &xml, const QString &id, bool doIt, QUndoCommand *parent = Q_NULLPTR);
|
||||
AddClipCommand(Bin *bin, const QDomElement &xml, const QString &id, bool doIt, QUndoCommand *parent = nullptr);
|
||||
void undo() Q_DECL_OVERRIDE;
|
||||
void redo() Q_DECL_OVERRIDE;
|
||||
private:
|
||||
|
||||
@@ -170,7 +170,7 @@ QUrl Generators::getSavedClip(QString clipFolder)
|
||||
if (fd.exec() != QDialog::Accepted || fd.selectedUrls().isEmpty()) {
|
||||
return QUrl();
|
||||
}
|
||||
QUrl url = fd.selectedUrls().first();
|
||||
QUrl url = fd.selectedUrls().constFirst();
|
||||
|
||||
if (url.isValid()) {
|
||||
#if KXMLGUI_VERSION_MINOR < 23 && KXMLGUI_VERSION_MAJOR == 5
|
||||
|
||||
@@ -48,7 +48,7 @@ class Generators : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Generators(Monitor *monitor, const QString &path, QWidget *parent = Q_NULLPTR);
|
||||
explicit Generators(Monitor *monitor, const QString &path, QWidget *parent = nullptr);
|
||||
virtual ~Generators();
|
||||
|
||||
static void getGenerators(const QStringList &producers, QMenu *menu);
|
||||
|
||||
@@ -76,7 +76,7 @@ ProjectClip::ProjectClip(const QDomElement &description, const QIcon &thumb, Pro
|
||||
, m_type(Unknown)
|
||||
, m_thumbsProducer(nullptr)
|
||||
{
|
||||
Q_ASSERT(description.hasAttribute("id"));
|
||||
Q_ASSERT(description.hasAttribute(QStringLiteral("id")));
|
||||
m_clipStatus = StatusWaiting;
|
||||
m_thumbnail = thumb;
|
||||
if (description.hasAttribute(QStringLiteral("type"))) {
|
||||
@@ -104,7 +104,9 @@ ProjectClip::~ProjectClip()
|
||||
// controller is deleted in bincontroller
|
||||
abortAudioThumbs();
|
||||
bin()->slotAbortAudioThumb(m_id, duration().ms());
|
||||
QMutexLocker audioLock(&m_audioMutex);
|
||||
if (m_controller) {
|
||||
QMutexLocker locker(&m_controller->producerMutex);
|
||||
}
|
||||
m_thumbMutex.lock();
|
||||
m_requestedThumbs.clear();
|
||||
m_thumbMutex.unlock();
|
||||
@@ -399,13 +401,13 @@ Mlt::Producer *ProjectClip::originalProducer()
|
||||
|
||||
Mlt::Producer *ProjectClip::thumbProducer()
|
||||
{
|
||||
QMutexLocker locker(&m_producerMutex);
|
||||
if (m_thumbsProducer) {
|
||||
return m_thumbsProducer;
|
||||
}
|
||||
if (!m_controller || m_controller->clipType() == Unknown) {
|
||||
return nullptr;
|
||||
}
|
||||
QMutexLocker locker(&m_controller->producerMutex);
|
||||
Mlt::Producer prod = m_controller->originalProducer();
|
||||
if (!prod.is_valid()) {
|
||||
return nullptr;
|
||||
@@ -674,6 +676,8 @@ void ProjectClip::setProperties(const QMap<QString, QString> &properties, bool r
|
||||
emit refreshAnalysisPanel();
|
||||
}
|
||||
if (properties.contains(QStringLiteral("length")) || properties.contains(QStringLiteral("kdenlive:duration"))) {
|
||||
refreshOnly = false;
|
||||
reload = true;
|
||||
m_duration = m_controller->getStringDuration();
|
||||
bin()->emitItemUpdated(this);
|
||||
}
|
||||
@@ -843,9 +847,9 @@ void ProjectClip::addEffect(const ProfileInfo &pInfo, QDomElement &effect)
|
||||
bin()->emitItemUpdated(this);
|
||||
}
|
||||
|
||||
void ProjectClip::updateEffect(const ProfileInfo &pInfo, QDomElement &effect, int ix, bool refreshStack)
|
||||
void ProjectClip::updateEffect(const ProfileInfo &pInfo, QDomElement &effect, int ix, bool refreshStack, bool updateClip)
|
||||
{
|
||||
m_controller->updateEffect(pInfo, effect, ix);
|
||||
m_controller->updateEffect(pInfo, effect, ix, updateClip);
|
||||
if (refreshStack) {
|
||||
bin()->updateMasterEffect(m_controller);
|
||||
}
|
||||
@@ -901,7 +905,7 @@ void ProjectClip::doExtractIntra()
|
||||
if (pos >= max) {
|
||||
pos = max - 1;
|
||||
}
|
||||
const QString path = url() + '_' + QString::number(pos);
|
||||
const QString path = url() + QLatin1Char('_') + QString::number(pos);
|
||||
QImage img = bin()->findCachedPixmap(path);
|
||||
if (!img.isNull()) {
|
||||
// Cache already contains image
|
||||
@@ -911,7 +915,7 @@ void ProjectClip::doExtractIntra()
|
||||
Mlt::Frame *frame = prod->get_frame();
|
||||
frame->set("deinterlace_method", "onefield");
|
||||
frame->set("top_field_first", -1);
|
||||
if (frame && frame->is_valid()) {
|
||||
if (frame->is_valid()) {
|
||||
img = KThumb::getFrame(frame, fullWidth, 150);
|
||||
bin()->cachePixmap(path, img);
|
||||
emit thumbReady(pos, img);
|
||||
@@ -948,14 +952,14 @@ void ProjectClip::doExtractImage()
|
||||
m_thumbMutex.lock();
|
||||
int pos = m_requestedThumbs.takeFirst();
|
||||
m_thumbMutex.unlock();
|
||||
if (ok && thumbFolder.exists(hash() + '#' + QString::number(pos) + ".png")) {
|
||||
emit thumbReady(pos, QImage(thumbFolder.absoluteFilePath(hash() + '#' + QString::number(pos) + ".png")));
|
||||
if (ok && thumbFolder.exists(hash() + QLatin1Char('#') + QString::number(pos) + QStringLiteral(".png"))) {
|
||||
emit thumbReady(pos, QImage(thumbFolder.absoluteFilePath(hash() + QLatin1Char('#') + QString::number(pos) + QStringLiteral(".png"))));
|
||||
continue;
|
||||
}
|
||||
if (pos >= max) {
|
||||
pos = max - 1;
|
||||
}
|
||||
const QString path = url() + '_' + QString::number(pos);
|
||||
const QString path = url() + QLatin1Char('_') + QString::number(pos);
|
||||
QImage img = bin()->findCachedPixmap(path);
|
||||
if (!img.isNull()) {
|
||||
emit thumbReady(pos, img);
|
||||
@@ -965,8 +969,8 @@ void ProjectClip::doExtractImage()
|
||||
Mlt::Frame *frame = prod->get_frame();
|
||||
frame->set("deinterlace_method", "onefield");
|
||||
frame->set("top_field_first", -1);
|
||||
if (frame && frame->is_valid()) {
|
||||
img = KThumb::getFrame(frame, frameWidth, 150);
|
||||
if (frame->is_valid()) {
|
||||
img = KThumb::getFrame(frame, frameWidth, 150, prod->profile()->sar() != 1);
|
||||
bin()->cachePixmap(path, img);
|
||||
emit thumbReady(pos, img);
|
||||
}
|
||||
@@ -1012,7 +1016,7 @@ const QString ProjectClip::getAudioThumbPath(AudioStreamInfo *audioInfo)
|
||||
QDir thumbFolder = bin()->getCacheDir(CacheAudio, &ok);
|
||||
QString audioPath = thumbFolder.absoluteFilePath(clipHash);
|
||||
if (audioStream > 0) {
|
||||
audioPath.append("_" + QString::number(audioInfo->audio_index()));
|
||||
audioPath.append(QLatin1Char('_') + QString::number(audioInfo->audio_index()));
|
||||
}
|
||||
int roundedFps = (int) m_controller->profile()->fps();
|
||||
audioPath.append(QStringLiteral("_%1_audio.png").arg(roundedFps));
|
||||
@@ -1021,7 +1025,10 @@ const QString ProjectClip::getAudioThumbPath(AudioStreamInfo *audioInfo)
|
||||
|
||||
void ProjectClip::slotCreateAudioThumbs()
|
||||
{
|
||||
QMutexLocker lock(&m_audioMutex);
|
||||
if (!m_controller) {
|
||||
return;
|
||||
}
|
||||
QMutexLocker locker(&m_controller->producerMutex);
|
||||
Mlt::Producer *prod = originalProducer();
|
||||
if (!prod || !prod->is_valid()) {
|
||||
return;
|
||||
@@ -1135,7 +1142,6 @@ void ProjectClip::slotCreateAudioThumbs()
|
||||
int dataSize = 0;
|
||||
QList<const qint16 *> rawChannels;
|
||||
QList<QByteArray> sourceChannels;
|
||||
QList<qint16> data2;
|
||||
for (int i = 0; i < channelFiles.count(); i++) {
|
||||
channelFiles[i]->open();
|
||||
QByteArray res = channelFiles[i]->readAll();
|
||||
@@ -1229,6 +1235,7 @@ void ProjectClip::slotCreateAudioThumbs()
|
||||
double framesPerSecond = audioProducer->get_fps();
|
||||
mlt_audio_format audioFormat = mlt_audio_s16;
|
||||
QStringList keys;
|
||||
keys.reserve(channels);
|
||||
for (int i = 0; i < channels; i++) {
|
||||
keys << "meta.media.audio_level." + QString::number(i);
|
||||
}
|
||||
@@ -1294,7 +1301,7 @@ void ProjectClip::updateFfmpegProgress()
|
||||
return;
|
||||
}
|
||||
QString result = callerProcess->readAllStandardOutput();
|
||||
const QStringList lines = result.split('\n');
|
||||
const QStringList lines = result.split(QLatin1Char('\n'));
|
||||
for (const QString &data : lines) {
|
||||
if (data.startsWith(QStringLiteral("out_time_ms"))) {
|
||||
long ms = data.section(QLatin1Char('='), 1).toLong();
|
||||
@@ -1351,7 +1358,7 @@ QStringList ProjectClip::updatedAnalysisData(const QString &name, const QString
|
||||
previous = m_controller->property("kdenlive:clipanalysis." + name + QString::number(i));
|
||||
}
|
||||
return QStringList() << QString("kdenlive:clipanalysis." + name + QString::number(i)) << geometryWithOffset(data, offset);
|
||||
//m_controller->setProperty("kdenlive:clipanalysis." + name + ' ' + QString::number(i), geometryWithOffset(data, offset));
|
||||
//m_controller->setProperty("kdenlive:clipanalysis." + name + QLatin1Char(' ') + QString::number(i), geometryWithOffset(data, offset));
|
||||
}
|
||||
} else {
|
||||
return QStringList() << QString("kdenlive:clipanalysis." + name) << geometryWithOffset(data, offset);
|
||||
@@ -1386,7 +1393,7 @@ const QString ProjectClip::geometryWithOffset(const QString &data, int offset)
|
||||
|
||||
QImage ProjectClip::findCachedThumb(int pos)
|
||||
{
|
||||
const QString path = url() + '_' + QString::number(pos);
|
||||
const QString path = url() + QLatin1Char('_') + QString::number(pos);
|
||||
return bin()->findCachedPixmap(path);
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Mlt
|
||||
{
|
||||
class Producer;
|
||||
class Properties;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @class ProjectClip
|
||||
@@ -71,14 +71,14 @@ public:
|
||||
/** @brief Returns a unique hash identifier used to store clip thumbnails. */
|
||||
//virtual void hash() = 0;
|
||||
|
||||
/** @brief Returns this if @param id matches the clip's id or Q_NULLPTR otherwise. */
|
||||
/** @brief Returns this if @param id matches the clip's id or nullptr otherwise. */
|
||||
ProjectClip *clip(const QString &id) Q_DECL_OVERRIDE;
|
||||
|
||||
ProjectFolder *folder(const QString &id) Q_DECL_OVERRIDE;
|
||||
|
||||
ProjectSubClip *getSubClip(int in, int out);
|
||||
|
||||
/** @brief Returns this if @param ix matches the clip's index or Q_NULLPTR otherwise. */
|
||||
/** @brief Returns this if @param ix matches the clip's index or nullptr otherwise. */
|
||||
ProjectClip *clipAt(int ix) Q_DECL_OVERRIDE;
|
||||
|
||||
/** @brief Recursively disable/enable bin effects. */
|
||||
@@ -193,7 +193,7 @@ public:
|
||||
void addMarkers(QList<CommentedTime> &markers);
|
||||
/** @brief Add an effect to bin clip. */
|
||||
void addEffect(const ProfileInfo &pInfo, QDomElement &effect);
|
||||
void updateEffect(const ProfileInfo &pInfo, QDomElement &effect, int ix, bool refreshStack);
|
||||
void updateEffect(const ProfileInfo &pInfo, QDomElement &effect, int ix, bool refreshStack, bool updateClip);
|
||||
void removeEffect(int ix);
|
||||
/** @brief Create audio thumbnail for this clip. */
|
||||
void createAudioThumbs();
|
||||
@@ -241,7 +241,6 @@ private:
|
||||
QMutex m_producerMutex;
|
||||
QMutex m_thumbMutex;
|
||||
QMutex m_intraThumbMutex;
|
||||
QMutex m_audioMutex;
|
||||
QFuture <void> m_thumbThread;
|
||||
QList<int> m_requestedThumbs;
|
||||
QFuture <void> m_intraThread;
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
* @param description element describing the folder and its children
|
||||
* @param parent parent folder
|
||||
*/
|
||||
ProjectFolder(const QString &id, const QString &name, ProjectFolder *parent = 0);
|
||||
ProjectFolder(const QString &id, const QString &name, ProjectFolder *parent = nullptr);
|
||||
|
||||
/** @brief Creates an empty root folder. */
|
||||
explicit ProjectFolder(Bin *bin);
|
||||
|
||||
@@ -139,7 +139,7 @@ bool ProjectItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action
|
||||
|
||||
if (data->hasFormat(QStringLiteral("kdenlive/producerslist"))) {
|
||||
// Dropping an Bin item
|
||||
QStringList ids = QString(data->data(QStringLiteral("kdenlive/producerslist"))).split(';');
|
||||
const QStringList ids = QString(data->data(QStringLiteral("kdenlive/producerslist"))).split(QLatin1Char(';'));
|
||||
emit itemDropped(ids, parent);
|
||||
return true;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ bool ProjectItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action
|
||||
}
|
||||
|
||||
if (data->hasFormat(QStringLiteral("kdenlive/clip"))) {
|
||||
QStringList list = QString(data->data(QStringLiteral("kdenlive/clip"))).split(';');
|
||||
const QStringList list = QString(data->data(QStringLiteral("kdenlive/clip"))).split(QLatin1Char(';'));
|
||||
emit addClipCut(list.at(0), list.at(1).toInt(), list.at(2).toInt());
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ QMimeData *ProjectItemModel::mimeData(const QModelIndexList &indices) const
|
||||
list << item->clipId();
|
||||
} else if (type == AbstractProjectItem::SubClipItem) {
|
||||
QPoint p = item->zone();
|
||||
list << item->clipId() + "/" + QString::number(p.x()) + "/" + QString::number(p.y());
|
||||
list << item->clipId() + QLatin1Char('/') + QString::number(p.x()) + QLatin1Char('/') + QString::number(p.y());
|
||||
} else if (type == AbstractProjectItem::FolderItem) {
|
||||
list << "#" + item->clipId();
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
/** @brief Mandatory reimplementation from QAbstractItemModel */
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
|
||||
/** @brief Returns the mimetype used for Drag actions */
|
||||
/** @brief Returns the MIME type used for Drag actions */
|
||||
QStringList mimeTypes() const Q_DECL_OVERRIDE;
|
||||
/** @brief Create data that will be used for Drag events */
|
||||
QMimeData *mimeData(const QModelIndexList &indices) const Q_DECL_OVERRIDE;
|
||||
|
||||
@@ -95,8 +95,16 @@ bool ProjectSortProxyModel::lessThan(const QModelIndex &left, const QModelIndex
|
||||
int rightType = sourceModel()->data(right, AbstractProjectItem::ItemTypeRole).toInt();
|
||||
if (leftType == rightType) {
|
||||
// Let the normal alphabetical sort happen
|
||||
QVariant leftData = sourceModel()->data(left, Qt::DisplayRole);
|
||||
QVariant rightData = sourceModel()->data(right, Qt::DisplayRole);
|
||||
QVariant leftData;
|
||||
QVariant rightData;
|
||||
if (leftType == AbstractProjectItem::SubClipItem) {
|
||||
// Subclips, sort by start position
|
||||
leftData = sourceModel()->data(left, AbstractProjectItem::DataDuration);
|
||||
rightData = sourceModel()->data(right, AbstractProjectItem::DataDuration);
|
||||
} else {
|
||||
leftData = sourceModel()->data(left, Qt::DisplayRole);
|
||||
rightData = sourceModel()->data(right, Qt::DisplayRole);
|
||||
}
|
||||
if (leftData.type() == QVariant::DateTime) {
|
||||
return leftData.toDateTime() < rightData.toDateTime();
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class ProjectSortProxyModel : public QSortFilterProxyModel
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ProjectSortProxyModel(QObject *parent = Q_NULLPTR);
|
||||
explicit ProjectSortProxyModel(QObject *parent = nullptr);
|
||||
QItemSelectionModel *selectionModel();
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -34,6 +34,7 @@ ProjectSubClip::ProjectSubClip(ProjectClip *parent, int in, int out, const QStri
|
||||
, m_in(in)
|
||||
, m_out(out)
|
||||
{
|
||||
m_duration = timecode;
|
||||
QPixmap pix(64, 36);
|
||||
pix.fill(Qt::lightGray);
|
||||
m_thumbnail = QIcon(pix);
|
||||
@@ -44,9 +45,8 @@ ProjectSubClip::ProjectSubClip(ProjectClip *parent, int in, int out, const QStri
|
||||
}
|
||||
m_clipStatus = StatusReady;
|
||||
setParent(parent);
|
||||
m_duration = timecode;
|
||||
// Save subclip in MLT
|
||||
parent->setProducerProperty("kdenlive:clipzone." + m_name, QString::number(in) + ";" + QString::number(out));
|
||||
parent->setProducerProperty("kdenlive:clipzone." + m_name, QString::number(in) + QLatin1Char(';') + QString::number(out));
|
||||
connect(parent, &ProjectClip::thumbReady, this, &ProjectSubClip::gotThumb);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ class QDomElement;
|
||||
|
||||
namespace Mlt
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @class ProjectSubClip
|
||||
|
||||
@@ -31,7 +31,7 @@ class ManageCapturesDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ManageCapturesDialog(const QList<QUrl> &files, QWidget *parent = Q_NULLPTR);
|
||||
explicit ManageCapturesDialog(const QList<QUrl> &files, QWidget *parent = nullptr);
|
||||
~ManageCapturesDialog();
|
||||
QList<QUrl> importFiles() const;
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ bool MltDeviceCapture::buildConsumer(const QString &profileName)
|
||||
}
|
||||
qputenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1");
|
||||
// OpenGL monitor
|
||||
m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_audio");
|
||||
m_mltConsumer = new Mlt::Consumer(*m_mltProfile, KdenliveSettings::audiobackend().toUtf8().constData());
|
||||
m_mltConsumer->set("preview_off", 1);
|
||||
m_mltConsumer->set("preview_format", mlt_image_rgb24);
|
||||
m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_gl_frame_show);
|
||||
@@ -223,7 +223,7 @@ void MltDeviceCapture::showFrame(Mlt::Frame &frame)
|
||||
int height = 0;
|
||||
const uchar *image = frame.get_image(format, width, height);
|
||||
QImage qimage(width, height, QImage::Format_RGB888);
|
||||
memcpy(qimage.scanLine(0), image, width * height * 3);
|
||||
memcpy(qimage.scanLine(0), image, static_cast<size_t>(width * height * 3));
|
||||
emit showImageSignal(qimage);
|
||||
|
||||
if (sendFrameForAnalysis && frame.get_frame()->convert_image) {
|
||||
@@ -249,7 +249,7 @@ void MltDeviceCapture::showAudio(Mlt::Frame &frame)
|
||||
// Data format: [ c00 c10 c01 c11 c02 c12 c03 c13 ... c0{samples-1} c1{samples-1} for 2 channels.
|
||||
// So the vector is of size samples*channels.
|
||||
audioShortVector sampleVector(samples * num_channels);
|
||||
memcpy(sampleVector.data(), data, samples * num_channels * sizeof(qint16));
|
||||
memcpy(sampleVector.data(), data, static_cast<size_t>(samples * num_channels * sizeof(qint16)));
|
||||
if (samples > 0) {
|
||||
emit audioSamplesSignal(sampleVector, freq, num_channels, samples);
|
||||
}
|
||||
@@ -307,7 +307,7 @@ void MltDeviceCapture::saveFrame(Mlt::Frame &frame)
|
||||
int height = 0;
|
||||
const uchar *image = frame.get_image(format, width, height);
|
||||
QImage qimage(width, height, QImage::Format_RGB888);
|
||||
memcpy(qimage.bits(), image, width * height * 3);
|
||||
memcpy(qimage.bits(), image, static_cast<size_t>(width * height * 3));
|
||||
|
||||
// Re-enable overlay
|
||||
Mlt::Service service(m_mltProducer->parent().get_service());
|
||||
@@ -366,10 +366,10 @@ bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &pa
|
||||
// without this line a call to mlt_properties_get_int(terminate on pause) for in mlt/src/modules/core/consumer_multi.c is returning 1
|
||||
// and going into and endless loop.
|
||||
renderProps->set("mlt_profile", m_activeProfile.toUtf8().constData());
|
||||
QStringList paramList = params.split(' ', QString::SkipEmptyParts);
|
||||
const QStringList paramList = params.split(' ', QString::SkipEmptyParts);
|
||||
for (int i = 0; i < paramList.count(); ++i) {
|
||||
tmp = qstrdup(paramList.at(i).section('=', 0, 0).toUtf8().constData());
|
||||
QString value = paramList.at(i).section('=', 1, 1);
|
||||
tmp = qstrdup(paramList.at(i).section(QLatin1Char('='), 0, 0).toUtf8().constData());
|
||||
QString value = paramList.at(i).section(QLatin1Char('='), 1, 1);
|
||||
if (value == QLatin1String("%threads")) {
|
||||
value = QString::number(QThread::idealThreadCount());
|
||||
}
|
||||
@@ -396,7 +396,7 @@ bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &pa
|
||||
qputenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1");
|
||||
|
||||
// OpenGL monitor
|
||||
previewProps->set("mlt_service", "sdl_audio");
|
||||
previewProps->set("mlt_service", KdenliveSettings::audiobackend().toUtf8().constData());
|
||||
previewProps->set("preview_off", 1);
|
||||
previewProps->set("preview_format", mlt_image_rgb24);
|
||||
previewProps->set("terminate_on_pause", 0);
|
||||
@@ -554,7 +554,7 @@ void MltDeviceCapture::setOverlayEffect(const QString &tag, const QStringList &p
|
||||
delete[] tmp;
|
||||
if (filter && filter->is_valid()) {
|
||||
for (int j = 0; j < parameters.count(); ++j) {
|
||||
filter->set(parameters.at(j).section('=', 0, 0).toUtf8().constData(), parameters.at(j).section('=', 1, 1).toUtf8().constData());
|
||||
filter->set(parameters.at(j).section(QLatin1Char('='), 0, 0).toUtf8().constData(), parameters.at(j).section(QLatin1Char('='), 1, 1).toUtf8().constData());
|
||||
}
|
||||
trackService.attach(*filter);
|
||||
}
|
||||
@@ -638,9 +638,9 @@ void MltDeviceCapture::uyvy2rgb(unsigned char *yuv_buffer, int width, int height
|
||||
b = 0;
|
||||
}
|
||||
|
||||
rgb_buffer[rgb_ptr] = r;
|
||||
rgb_buffer[rgb_ptr + 1] = g;
|
||||
rgb_buffer[rgb_ptr + 2] = b;
|
||||
rgb_buffer[rgb_ptr] = static_cast<uchar>(r);
|
||||
rgb_buffer[rgb_ptr + 1] = static_cast<uchar>(g);
|
||||
rgb_buffer[rgb_ptr + 2] = static_cast<uchar>(b);
|
||||
rgb_ptr += 3;
|
||||
|
||||
r = ((298 * (Y2 - 16) + 409 * (V - 128) + 128) >> 8);
|
||||
@@ -667,9 +667,9 @@ void MltDeviceCapture::uyvy2rgb(unsigned char *yuv_buffer, int width, int height
|
||||
b = 0;
|
||||
}
|
||||
|
||||
rgb_buffer[rgb_ptr] = r;
|
||||
rgb_buffer[rgb_ptr + 1] = g;
|
||||
rgb_buffer[rgb_ptr + 2] = b;
|
||||
rgb_buffer[rgb_ptr] = static_cast<uchar>(r);
|
||||
rgb_buffer[rgb_ptr + 1] = static_cast<uchar>(g);
|
||||
rgb_buffer[rgb_ptr + 2] = static_cast<uchar>(b);
|
||||
rgb_ptr += 3;
|
||||
}
|
||||
//emit imageReady(image);
|
||||
|
||||
@@ -30,11 +30,12 @@
|
||||
#include "definitions.h"
|
||||
#include "monitor/abstractmonitor.h"
|
||||
|
||||
#include <mlt/framework/mlt_types.h>
|
||||
|
||||
#include <QTimer>
|
||||
#include <QMutex>
|
||||
|
||||
// include after QTimer to have C++ phtreads defined
|
||||
#include <mlt/framework/mlt_types.h>
|
||||
|
||||
namespace Mlt
|
||||
{
|
||||
class Consumer;
|
||||
@@ -54,7 +55,7 @@ Q_OBJECT public:
|
||||
/** @brief Build a MLT 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 capture (default one will be used if empty). */
|
||||
explicit MltDeviceCapture(QString profile, /*VideoSurface *surface,*/ QWidget *parent = Q_NULLPTR);
|
||||
explicit MltDeviceCapture(QString profile, /*VideoSurface *surface,*/ QWidget *parent = nullptr);
|
||||
|
||||
/** @brief Destroy the MLT Renderer. */
|
||||
~MltDeviceCapture();
|
||||
|
||||
@@ -23,7 +23,7 @@ ColorTools::ColorTools(QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
QImage ColorTools::yuvColorWheel(const QSize &size, const unsigned char &Y, const float &scaling, const bool &modifiedVersion, const bool &circleOnly)
|
||||
QImage ColorTools::yuvColorWheel(const QSize &size, int Y, float scaling, bool modifiedVersion, bool circleOnly)
|
||||
{
|
||||
QImage wheel(size, QImage::Format_ARGB32);
|
||||
if (size.width() == 0 || size.height() == 0) {
|
||||
@@ -114,7 +114,7 @@ QImage ColorTools::yuvColorWheel(const QSize &size, const unsigned char &Y, cons
|
||||
return wheel;
|
||||
}
|
||||
|
||||
QImage ColorTools::yuvVerticalPlane(const QSize &size, const float &angle, const float &scaling)
|
||||
QImage ColorTools::yuvVerticalPlane(const QSize &size, int angle, float scaling)
|
||||
{
|
||||
QImage plane(size, QImage::Format_ARGB32);
|
||||
if (size.width() == 0 || size.height() == 0) {
|
||||
@@ -252,7 +252,7 @@ QImage ColorTools::rgbCurveLine(const QSize &size, const ColorTools::ColorsRGB &
|
||||
return plane;
|
||||
}
|
||||
|
||||
QImage ColorTools::yPbPrColorWheel(const QSize &size, const unsigned char &Y, const float &scaling, const bool &circleOnly)
|
||||
QImage ColorTools::yPbPrColorWheel(const QSize &size, int Y, float scaling, bool circleOnly)
|
||||
{
|
||||
|
||||
QImage wheel(size, QImage::Format_ARGB32);
|
||||
@@ -325,7 +325,7 @@ QImage ColorTools::yPbPrColorWheel(const QSize &size, const unsigned char &Y, co
|
||||
return wheel;
|
||||
}
|
||||
|
||||
QImage ColorTools::hsvHueShiftPlane(const QSize &size, const uint &S, const uint &V, const int &MIN, const int &MAX)
|
||||
QImage ColorTools::hsvHueShiftPlane(const QSize &size, int S, int V, int MIN, int MAX)
|
||||
{
|
||||
Q_ASSERT(size.width() > 0);
|
||||
Q_ASSERT(size.height() > 0);
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
If not the full rect should be filled, set circleOnly to true.
|
||||
See also: http://en.wikipedia.org/wiki/YUV and http://de.wikipedia.org/wiki/Vektorskop
|
||||
*/
|
||||
QImage yuvColorWheel(const QSize &size, const unsigned char &Y, const float &scaling, const bool &modifiedVersion, const bool &circleOnly);
|
||||
QImage yuvColorWheel(const QSize& size, int Y, float scaling, bool modifiedVersion, bool circleOnly);
|
||||
/**
|
||||
@brief Draws a UV plane with given UV angle (ratio u:v stays constant)
|
||||
scaling defines how far to zoom in (or out). Lower value = zoom in.
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
is then laid through the UV plane, with the defined angle.
|
||||
@see yuvColorWheel()
|
||||
*/
|
||||
QImage yuvVerticalPlane(const QSize &size, const float &angle, const float &scaling);
|
||||
QImage yuvVerticalPlane(const QSize& size, int angle, float scaling);
|
||||
/**
|
||||
@brief Draws a RGB plane with two values on one axis and one on the other.
|
||||
This is e.g. useful as background for a curves dialog. On the line from bottom left to top right
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
scaling defines how far to zoom in (or out). Lower value = zoom in.
|
||||
See also: http://de.wikipedia.org/wiki/YPbPr-Farbmodell and http://www.poynton.com/ColorFAQ.html
|
||||
*/
|
||||
QImage yPbPrColorWheel(const QSize &size, const unsigned char &Y, const float &scaling, const bool &circleOnly);
|
||||
QImage yPbPrColorWheel(const QSize &size, int Y, float scaling, bool circleOnly);
|
||||
/**
|
||||
@brief Draws a HSV plane with Hue on the x axis and hue difference on the y axis.
|
||||
This is for the Bézier Curves widget which allows to change the hue (y) of a certain hue.
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
For the value ranges see:
|
||||
http://doc.qt.nokia.com/latest/qcolor.html#the-hsv-color-model
|
||||
*/
|
||||
static QImage hsvHueShiftPlane(const QSize &size, const uint &S, const uint &V, const int &MIN, const int &MAX);
|
||||
static QImage hsvHueShiftPlane(const QSize &size, int S, int V, int MIN, int MAX);
|
||||
|
||||
/**
|
||||
Basic HSV plane with two components varying on the x and y axis.
|
||||
|
||||
88
src/core.cpp
88
src/core.cpp
@@ -10,15 +10,23 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
|
||||
#include "core.h"
|
||||
#include "mainwindow.h"
|
||||
#include "kdenlivesettings.h"
|
||||
#include "project/projectmanager.h"
|
||||
#include "monitor/monitormanager.h"
|
||||
#include "mltconnection.h"
|
||||
#include "profiles/profilerepository.hpp"
|
||||
#include "mltcontroller/bincontroller.h"
|
||||
#include "mltcontroller/producerqueue.h"
|
||||
#include "bin/bin.h"
|
||||
#include "library/librarywidget.h"
|
||||
#include <QCoreApplication>
|
||||
#include "kdenlive_debug.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <KMessageBox>
|
||||
#include <QInputDialog>
|
||||
|
||||
#include <mlt++/MltRepository.h>
|
||||
|
||||
#include <locale>
|
||||
#ifdef Q_OS_MAC
|
||||
#include <xlocale.h>
|
||||
@@ -26,8 +34,8 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
|
||||
Core *Core::m_self = nullptr;
|
||||
|
||||
Core::Core(MainWindow *mainWindow) :
|
||||
m_mainWindow(mainWindow)
|
||||
Core::Core() :
|
||||
m_mainWindow(nullptr)
|
||||
, m_projectManager(nullptr)
|
||||
, m_monitorManager(nullptr)
|
||||
, m_binController(nullptr)
|
||||
@@ -49,14 +57,76 @@ Core::~Core()
|
||||
m_self = nullptr;
|
||||
}
|
||||
|
||||
void Core::build(MainWindow *mainWindow)
|
||||
void Core::build(const QString &MltPath, const QUrl &Url, const QString &clipsToLoad)
|
||||
{
|
||||
m_self = new Core(mainWindow);
|
||||
m_self = new Core();
|
||||
m_self->initLocale();
|
||||
|
||||
qRegisterMetaType<audioShortVector> ("audioShortVector");
|
||||
qRegisterMetaType< QVector<double> > ("QVector<double>");
|
||||
qRegisterMetaType<MessageType> ("MessageType");
|
||||
qRegisterMetaType<stringMap> ("stringMap");
|
||||
qRegisterMetaType<audioByteArray> ("audioByteArray");
|
||||
qRegisterMetaType< QList<ItemInfo> > ("QList<ItemInfo>");
|
||||
qRegisterMetaType< QVector<int> > ();
|
||||
qRegisterMetaType<QDomElement> ("QDomElement");
|
||||
qRegisterMetaType<requestClipInfo> ("requestClipInfo");
|
||||
qRegisterMetaType<MltVideoProfile> ("MltVideoProfile");
|
||||
|
||||
m_self->initialize(MltPath);
|
||||
m_self->m_mainWindow->init(MltPath, Url, clipsToLoad);
|
||||
if (qApp->isSessionRestored()) {
|
||||
//NOTE: we are restoring only one window, because Kdenlive only uses one MainWindow
|
||||
m_self->m_mainWindow->restore(1, false);
|
||||
}
|
||||
m_self->m_mainWindow->show();
|
||||
}
|
||||
|
||||
void Core::initialize()
|
||||
void Core::initialize(const QString &mltPath)
|
||||
{
|
||||
m_mltConnection = std::unique_ptr<MltConnection>(new MltConnection(mltPath));
|
||||
m_mainWindow = new MainWindow();
|
||||
|
||||
//loads the profile from disk
|
||||
ProfileRepository::get()->refresh();
|
||||
|
||||
//load default profile and ask user to select one if not found.
|
||||
m_profile = KdenliveSettings::default_profile();
|
||||
if (m_profile.isEmpty()) {
|
||||
m_profile = ProjectManager::getDefaultProjectFormat();
|
||||
KdenliveSettings::setDefault_profile(m_profile);
|
||||
}
|
||||
if (!ProfileRepository::get()->profileExists(m_profile)) {
|
||||
KMessageBox::sorry(m_mainWindow, i18n("The default profile of Kdenlive is not set or invalid, press OK to set it to a correct value."));
|
||||
|
||||
//TODO this simple widget should be improved and probably use profileWidget
|
||||
//we get the list of profiles
|
||||
QVector<QPair<QString, QString>> all_profiles = ProfileRepository::get()->getAllProfiles();
|
||||
QStringList all_descriptions;
|
||||
for (const auto& profile : all_profiles) {
|
||||
all_descriptions << profile.first;
|
||||
}
|
||||
|
||||
//ask the user
|
||||
bool ok;
|
||||
QString item = QInputDialog::getItem(m_mainWindow, i18n("Select Default Profile"),
|
||||
i18n("Profile:"), all_descriptions, 0, false, &ok);
|
||||
if (ok) {
|
||||
ok = false;
|
||||
for (const auto& profile : all_profiles) {
|
||||
if (profile.first == item) {
|
||||
m_profile = profile.second;
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
KMessageBox::error(m_mainWindow, i18n("The given profile is invalid. We default to the profile \"dv_pal\", but you can change this from Kdenlive's settings panel"));
|
||||
m_profile = "dv_pal";
|
||||
}
|
||||
KdenliveSettings::setDefault_profile(m_profile);
|
||||
}
|
||||
|
||||
m_projectManager = new ProjectManager(this);
|
||||
m_binWidget = new Bin();
|
||||
m_binController = new BinController();
|
||||
@@ -81,7 +151,6 @@ void Core::initialize()
|
||||
//TODO
|
||||
/*connect(m_producerQueue, SIGNAL(removeInvalidProxy(QString,bool)), m_binWidget, SLOT(slotRemoveInvalidProxy(QString,bool)));*/
|
||||
|
||||
emit coreIsReady();
|
||||
}
|
||||
|
||||
Core *Core::self()
|
||||
@@ -154,3 +223,8 @@ void Core::initLocale()
|
||||
QLocale::setDefault(systemLocale);
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Mlt::Repository>& Core::getMltRepository()
|
||||
{
|
||||
return m_mltConnection->getMltRepository();
|
||||
}
|
||||
|
||||
42
src/core.h
42
src/core.h
@@ -11,7 +11,9 @@ the Free Software Foundation, either version 3 of the License, or
|
||||
#ifndef CORE_H
|
||||
#define CORE_H
|
||||
|
||||
#include <memory>
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
#include "kdenlivecore_export.h"
|
||||
|
||||
class MainWindow;
|
||||
@@ -21,7 +23,14 @@ class BinController;
|
||||
class Bin;
|
||||
class LibraryWidget;
|
||||
class ProducerQueue;
|
||||
class MltConnection;
|
||||
|
||||
namespace Mlt
|
||||
{
|
||||
class Repository;
|
||||
}
|
||||
|
||||
#define EXIT_RESTART (42)
|
||||
#define pCore Core::self()
|
||||
|
||||
/**
|
||||
@@ -37,20 +46,27 @@ class /*KDENLIVECORE_EXPORT*/ Core : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Core(const Core&) = delete;
|
||||
Core& operator=( const Core& ) = delete;
|
||||
Core(Core&&) = delete;
|
||||
Core& operator=(Core&&) = delete;
|
||||
|
||||
virtual ~Core();
|
||||
|
||||
/**
|
||||
* @brief Constructs the singleton object and the managers.
|
||||
* @param mainWindow pointer to MainWindow
|
||||
*/
|
||||
static void build(MainWindow *mainWindow);
|
||||
* @brief Constructs the application
|
||||
* @param MltPath (optional) path to MLT environment
|
||||
* @param Url (optional) file to open
|
||||
* @param clipsToLoad (optional) a comma separated list of clips to import in project
|
||||
*
|
||||
* If Url is present, it will be opened, otherwhise, if openlastproject is
|
||||
* set, latest project will be opened. If no file is open after trying this,
|
||||
* a default new file will be created. */
|
||||
static void build(const QString &MltPath = QString(), const QUrl &Url = QUrl(), const QString &clipsToLoad = QString());
|
||||
|
||||
/** @brief Returns a pointer to the singleton object. */
|
||||
static Core *self();
|
||||
|
||||
/** @brief Builds all necessary parts. */
|
||||
void initialize();
|
||||
|
||||
/** @brief Returns a pointer to the main window. */
|
||||
MainWindow *window();
|
||||
|
||||
@@ -67,10 +83,16 @@ public:
|
||||
/** @brief Returns a pointer to the library. */
|
||||
LibraryWidget *library();
|
||||
|
||||
/** @brief Returns a pointer to MLT's repository */
|
||||
std::unique_ptr<Mlt::Repository>& getMltRepository();
|
||||
|
||||
private:
|
||||
explicit Core(MainWindow *mainWindow);
|
||||
explicit Core();
|
||||
static Core *m_self;
|
||||
|
||||
/** @brief Builds all necessary parts. */
|
||||
void initialize(const QString &mltPath);
|
||||
|
||||
/** @brief Makes sure Qt's locale and system locale settings match. */
|
||||
void initLocale();
|
||||
|
||||
@@ -82,6 +104,10 @@ private:
|
||||
Bin *m_binWidget;
|
||||
LibraryWidget *m_library;
|
||||
|
||||
std::unique_ptr<MltConnection> m_mltConnection;
|
||||
|
||||
QString m_profile;
|
||||
|
||||
signals:
|
||||
void coreIsReady();
|
||||
void updateLibraryPath();
|
||||
|
||||
@@ -190,14 +190,14 @@ void CommentedTime::setComment(const QString &comm)
|
||||
c = comm;
|
||||
}
|
||||
|
||||
void CommentedTime::setMarkerType(int t)
|
||||
void CommentedTime::setMarkerType(int newtype)
|
||||
{
|
||||
type = t;
|
||||
type = newtype;
|
||||
}
|
||||
|
||||
QString CommentedTime::hash() const
|
||||
{
|
||||
return QString::number(type) + ":" + (c.isEmpty() ? i18n("Marker") : c);
|
||||
return QString::number(type) + QLatin1Char(':') + (c.isEmpty() ? i18n("Marker") : c);
|
||||
}
|
||||
|
||||
int CommentedTime::markerType() const
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
|
||||
#include "gentime.h"
|
||||
#include "effectslist/effectslist.h"
|
||||
|
||||
#include "kdenlive_debug.h"
|
||||
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QString>
|
||||
#include <QHash>
|
||||
|
||||
const int MAXCLIPDURATION = 15000;
|
||||
|
||||
@@ -79,7 +79,7 @@ enum ClipState {
|
||||
Disabled = 3
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
namespace TimelineMode
|
||||
{
|
||||
@@ -88,7 +88,7 @@ enum EditMode {
|
||||
OverwriteEdit = 1,
|
||||
InsertEdit = 2
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
enum ClipType {
|
||||
Unknown = 0,
|
||||
@@ -216,7 +216,7 @@ struct requestClipInfo {
|
||||
int imageHeight;
|
||||
bool replaceProducer;
|
||||
|
||||
bool operator==(const requestClipInfo &a)
|
||||
bool operator==(const requestClipInfo &a) const
|
||||
{
|
||||
return clipId == a.clipId;
|
||||
}
|
||||
@@ -251,7 +251,7 @@ public:
|
||||
}
|
||||
return (pos <= endPos && pos >= startPos);
|
||||
}
|
||||
bool operator==(const ItemInfo &a)
|
||||
bool operator==(const ItemInfo &a) const
|
||||
{
|
||||
return startPos == a.startPos && endPos == a.endPos && track == a.track && cropStart == a.cropStart;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ public:
|
||||
|
||||
QString comment() const;
|
||||
GenTime time() const;
|
||||
/** @brief Returns a string containing infos needed to store marker info. string equals marker type + ":" + marker comment */
|
||||
/** @brief Returns a string containing infos needed to store marker info. string equals marker type + QLatin1Char(':') + marker comment */
|
||||
QString hash() const;
|
||||
void setComment(const QString &comm);
|
||||
void setMarkerType(int t);
|
||||
@@ -343,4 +343,17 @@ private:
|
||||
QDebug operator << (QDebug qd, const ItemInfo &info);
|
||||
QDebug operator << (QDebug qd, const MltVideoProfile &profile);
|
||||
|
||||
//we provide hash function for qstring
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<QString>
|
||||
{
|
||||
std::size_t operator()(const QString& k) const
|
||||
{
|
||||
return qHash(k);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,6 +20,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "clipcreationdialog.h"
|
||||
#include "kdenlive_debug.h"
|
||||
#include "kdenlivesettings.h"
|
||||
#include "doc/kdenlivedoc.h"
|
||||
#include "bin/bin.h"
|
||||
@@ -51,16 +52,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// static
|
||||
QStringList ClipCreationDialog::getExtensions()
|
||||
{
|
||||
// Build list of mime types
|
||||
// Build list of MIME types
|
||||
QStringList mimeTypes = QStringList() << QStringLiteral("application/x-kdenlive") << QStringLiteral("application/x-kdenlivetitle") << QStringLiteral("video/mlt-playlist") << QStringLiteral("text/plain");
|
||||
|
||||
// Video mimes
|
||||
// Video MIMEs
|
||||
mimeTypes << QStringLiteral("video/x-flv") << QStringLiteral("application/vnd.rn-realmedia") << QStringLiteral("video/x-dv") << QStringLiteral("video/dv") << QStringLiteral("video/x-msvideo") << QStringLiteral("video/x-matroska") << QStringLiteral("video/mpeg") << QStringLiteral("video/ogg") << QStringLiteral("video/x-ms-wmv") << QStringLiteral("video/mp4") << QStringLiteral("video/quicktime") << QStringLiteral("video/webm") << QStringLiteral("video/3gpp") << QStringLiteral("video/mp2t");
|
||||
|
||||
// Audio mimes
|
||||
// Audio MIMEs
|
||||
mimeTypes << QStringLiteral("audio/x-flac") << QStringLiteral("audio/x-matroska") << QStringLiteral("audio/mp4") << QStringLiteral("audio/mpeg") << QStringLiteral("audio/x-mp3") << QStringLiteral("audio/ogg") << QStringLiteral("audio/x-wav") << QStringLiteral("audio/x-aiff") << QStringLiteral("audio/aiff") << QStringLiteral("application/ogg") << QStringLiteral("application/mxf") << QStringLiteral("application/x-shockwave-flash") << QStringLiteral("audio/ac3");
|
||||
|
||||
// Image mimes
|
||||
// Image MIMEs
|
||||
mimeTypes << QStringLiteral("image/gif") << QStringLiteral("image/jpeg") << QStringLiteral("image/png") << QStringLiteral("image/x-tga") << QStringLiteral("image/x-bmp") << QStringLiteral("image/svg+xml") << QStringLiteral("image/tiff") << QStringLiteral("image/x-xcf") << QStringLiteral("image/x-xcf-gimp") << QStringLiteral("image/x-vnd.adobe.photoshop") << QStringLiteral("image/x-pcx") << QStringLiteral("image/x-exr") << QStringLiteral("image/x-portable-pixmap") << QStringLiteral("application/x-krita");
|
||||
|
||||
QMimeDatabase db;
|
||||
@@ -71,6 +72,22 @@ QStringList ClipCreationDialog::getExtensions()
|
||||
allExtensions.append(mime.globPatterns());
|
||||
}
|
||||
}
|
||||
// process custom user extensions
|
||||
const QStringList customs = KdenliveSettings::addedExtensions().split(' ', QString::SkipEmptyParts);
|
||||
if (!customs.isEmpty()) {
|
||||
for (const QString &ext : customs) {
|
||||
if (ext.startsWith(QLatin1String("*."))) {
|
||||
allExtensions << ext;
|
||||
} else if (ext.startsWith(QLatin1String("."))) {
|
||||
allExtensions << QStringLiteral("*") + ext;
|
||||
} else if (!ext.contains(QLatin1Char('.'))) {
|
||||
allExtensions << QStringLiteral("*.") + ext;
|
||||
} else {
|
||||
//Unrecognized format
|
||||
qCDebug(KDENLIVE_LOG)<<"Unrecognized custom format: "<<ext;
|
||||
}
|
||||
}
|
||||
}
|
||||
allExtensions.removeDuplicates();
|
||||
return allExtensions;
|
||||
}
|
||||
@@ -81,7 +98,7 @@ void ClipCreationDialog::createClipFromXml(KdenliveDoc *doc, QDomElement &xml, c
|
||||
//FIXME?
|
||||
Q_UNUSED(groupInfo)
|
||||
|
||||
uint id = bin->getFreeClipId();
|
||||
int id = bin->getFreeClipId();
|
||||
xml.setAttribute(QStringLiteral("id"), QString::number(id));
|
||||
AddClipCommand *command = new AddClipCommand(bin, xml, QString::number(id), true);
|
||||
doc->commandStack()->push(command);
|
||||
@@ -110,7 +127,7 @@ void ClipCreationDialog::createColorClip(KdenliveDoc *doc, const QStringList &gr
|
||||
QDomElement prod = xml.createElement(QStringLiteral("producer"));
|
||||
xml.appendChild(prod);
|
||||
prod.setAttribute(QStringLiteral("type"), (int) Color);
|
||||
uint id = bin->getFreeClipId();
|
||||
int id = bin->getFreeClipId();
|
||||
prod.setAttribute(QStringLiteral("id"), QString::number(id));
|
||||
prod.setAttribute(QStringLiteral("in"), QStringLiteral("0"));
|
||||
prod.setAttribute(QStringLiteral("length"), doc->getFramePos(doc->timecode().getTimecode(t->gentime())));
|
||||
@@ -171,7 +188,7 @@ void ClipCreationDialog::createQTextClip(KdenliveDoc *doc, const QStringList &gr
|
||||
QDomElement prod = xml.createElement(QStringLiteral("producer"));
|
||||
xml.appendChild(prod);
|
||||
prod.setAttribute(QStringLiteral("type"), (int) QText);
|
||||
uint id = bin->getFreeClipId();
|
||||
int id = bin->getFreeClipId();
|
||||
prod.setAttribute(QStringLiteral("id"), QString::number(id));
|
||||
|
||||
prod.setAttribute(QStringLiteral("in"), QStringLiteral("0"));
|
||||
@@ -250,7 +267,7 @@ void ClipCreationDialog::createSlideshowClip(KdenliveDoc *doc, const QStringList
|
||||
properties.insert(QStringLiteral("kdenlive:folderid"), groupInfo.at(0));
|
||||
}
|
||||
addXmlProperties(prod, properties);
|
||||
uint id = bin->getFreeClipId();
|
||||
int id = bin->getFreeClipId();
|
||||
AddClipCommand *command = new AddClipCommand(bin, xml.documentElement(), QString::number(id), true);
|
||||
doc->commandStack()->push(command);
|
||||
}
|
||||
@@ -270,7 +287,7 @@ void ClipCreationDialog::createTitleClip(KdenliveDoc *doc, const QStringList &gr
|
||||
QDomElement prod = xml.createElement(QStringLiteral("producer"));
|
||||
xml.appendChild(prod);
|
||||
//prod.setAttribute("resource", imagePath);
|
||||
uint id = bin->getFreeClipId();
|
||||
int id = bin->getFreeClipId();
|
||||
prod.setAttribute(QStringLiteral("id"), QString::number(id));
|
||||
|
||||
QMap<QString, QString> properties;
|
||||
@@ -309,7 +326,7 @@ void ClipCreationDialog::createTitleTemplateClip(KdenliveDoc *doc, const QString
|
||||
properties.insert(QStringLiteral("kdenlive:folderid"), groupInfo.at(0));
|
||||
}
|
||||
addXmlProperties(prod, properties);
|
||||
uint id = bin->getFreeClipId();
|
||||
int id = bin->getFreeClipId();
|
||||
prod.setAttribute(QStringLiteral("id"), QString::number(id));
|
||||
prod.setAttribute(QStringLiteral("type"), (int) TextTemplate);
|
||||
prod.setAttribute(QStringLiteral("transparency"), QStringLiteral("1"));
|
||||
@@ -429,7 +446,7 @@ void ClipCreationDialog::createClipsCommand(KdenliveDoc *doc, const QList<QUrl>
|
||||
i.next();
|
||||
properties.insert(i.key(), i.value());
|
||||
}
|
||||
uint id = bin->getFreeClipId();
|
||||
int id = bin->getFreeClipId();
|
||||
prod.setAttribute(QStringLiteral("id"), QString::number(id));
|
||||
QMimeDatabase db;
|
||||
QMimeType type = db.mimeTypeForUrl(file);
|
||||
@@ -449,8 +466,8 @@ void ClipCreationDialog::createClipsCommand(KdenliveDoc *doc, const QList<QUrl>
|
||||
prod.setAttribute(QStringLiteral("type"), (int) Text);
|
||||
// extract embedded images
|
||||
QDomNodeList items = txtdoc.elementsByTagName(QStringLiteral("content"));
|
||||
for (int i = 0; i < items.count(); ++i) {
|
||||
QDomElement content = items.item(i).toElement();
|
||||
for (int j = 0; j < items.count(); ++j) {
|
||||
QDomElement content = items.item(j).toElement();
|
||||
if (content.hasAttribute(QStringLiteral("base64"))) {
|
||||
QString titlesFolder = doc->projectDataFolder() + QStringLiteral("/titles/");
|
||||
QString path = TitleDocument::extractBase64Image(titlesFolder, content.attribute(QStringLiteral("base64")));
|
||||
@@ -493,7 +510,7 @@ void ClipCreationDialog::createClipsCommand(KdenliveDoc *doc, const QStringList
|
||||
{
|
||||
QList<QUrl> list;
|
||||
QString allExtensions = getExtensions().join(QLatin1Char(' '));
|
||||
QString dialogFilter = allExtensions + "|" + i18n("All Supported Files") + "\n*|" + i18n("All Files");
|
||||
QString dialogFilter = allExtensions + QLatin1Char('|') + i18n("All Supported Files") + QStringLiteral("\n*|") + i18n("All Files");
|
||||
QCheckBox *b = new QCheckBox(i18n("Import image sequence"));
|
||||
b->setChecked(KdenliveSettings::autoimagesequence());
|
||||
QCheckBox *c = new QCheckBox(i18n("Transparent background for images"));
|
||||
@@ -533,9 +550,9 @@ void ClipCreationDialog::createClipsCommand(KdenliveDoc *doc, const QStringList
|
||||
KdenliveSettings::setAutoimagetransparency(c->isChecked());
|
||||
list = fileWidget->selectedUrls();
|
||||
if (!list.isEmpty()) {
|
||||
KRecentDirs::add(QStringLiteral(":KdenliveClipFolder"), list.first().adjusted(QUrl::RemoveFilename).toLocalFile());
|
||||
KRecentDirs::add(QStringLiteral(":KdenliveClipFolder"), list.constFirst().adjusted(QUrl::RemoveFilename).toLocalFile());
|
||||
}
|
||||
if (b->isChecked() && list.count() == 1) {
|
||||
if (b->isChecked() && list.count() >= 1) {
|
||||
// Check for image sequence
|
||||
QUrl url = list.at(0);
|
||||
QString fileName = url.fileName().section(QLatin1Char('.'), 0, -2);
|
||||
@@ -543,10 +560,10 @@ void ClipCreationDialog::createClipsCommand(KdenliveDoc *doc, const QStringList
|
||||
KFileItem item(url);
|
||||
if (item.mimetype().startsWith(QLatin1String("image"))) {
|
||||
// import as sequence if we found more than one image in the sequence
|
||||
QStringList list;
|
||||
QString pattern = SlideshowClip::selectedPath(url, false, QString(), &list);
|
||||
qCDebug(KDENLIVE_LOG) << " / // IMPORT PATTERN: " << pattern << " COUNT: " << list.count();
|
||||
int count = list.count();
|
||||
QStringList patternlist;
|
||||
QString pattern = SlideshowClip::selectedPath(url, false, QString(), &patternlist);
|
||||
qCDebug(KDENLIVE_LOG) << " / // IMPORT PATTERN: " << pattern << " COUNT: " << patternlist.count();
|
||||
int count = patternlist.count();
|
||||
if (count > 1) {
|
||||
delete fileWidget;
|
||||
delete dlg;
|
||||
@@ -572,7 +589,7 @@ void ClipCreationDialog::createClipsCommand(KdenliveDoc *doc, const QStringList
|
||||
properties.insert(QStringLiteral("kdenlive:folderid"), groupInfo.at(0));
|
||||
}
|
||||
addXmlProperties(prod, properties);
|
||||
uint id = bin->getFreeClipId();
|
||||
int id = bin->getFreeClipId();
|
||||
AddClipCommand *command = new AddClipCommand(bin, xml.documentElement(), QString::number(id), true);
|
||||
doc->commandStack()->push(command);
|
||||
return;
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace ClipCreationDialog
|
||||
|
||||
QStringList getExtensions();
|
||||
void createColorClip(KdenliveDoc *doc, const QStringList &groupInfo, Bin *bin);
|
||||
void createQTextClip(KdenliveDoc *doc, const QStringList &groupInfo, Bin *bin, ProjectClip *clip = Q_NULLPTR);
|
||||
void createQTextClip(KdenliveDoc *doc, const QStringList &groupInfo, Bin *bin, ProjectClip *clip = nullptr);
|
||||
void createClipFromXml(KdenliveDoc *doc, QDomElement &xml, const QStringList &groupInfo, Bin *bin);
|
||||
void createSlideshowClip(KdenliveDoc *doc, const QStringList &groupInfo, Bin *bin);
|
||||
void createTitleClip(KdenliveDoc *doc, const QStringList &groupInfo, const QString &templatePath, Bin *bin);
|
||||
@@ -49,7 +49,7 @@ void createClipsCommand(KdenliveDoc *doc, const QList<QUrl> &urls, const QString
|
||||
void createClipsCommand(Bin *bin, const QDomElement &producer, const QString &id, QUndoCommand *command);
|
||||
void createClipsCommand(KdenliveDoc *doc, const QStringList &groupInfo, Bin *bin);
|
||||
void addXmlProperties(QDomElement &producer, QMap<QString, QString> &properties);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ void EncodingProfilesDialog::slotShowParams()
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
profile_parameters->setPlainText(item->data(Qt::UserRole).toString().section(';', 0, 0));
|
||||
profile_parameters->setPlainText(item->data(Qt::UserRole).toString().section(QLatin1Char(';'), 0, 0));
|
||||
}
|
||||
|
||||
void EncodingProfilesDialog::slotDeleteProfile()
|
||||
@@ -145,12 +145,12 @@ void EncodingProfilesDialog::slotAddProfile()
|
||||
|
||||
QListWidgetItem *item = profile_list->currentItem();
|
||||
if (item) {
|
||||
QString data = item->data(Qt::UserRole).toString();
|
||||
pparams->setPlainText(data.section(';', 0, 0));
|
||||
pext->setText(data.section(';', 1, 1));
|
||||
QString profilestr = item->data(Qt::UserRole).toString();
|
||||
pparams->setPlainText(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
pext->setText(profilestr.section(QLatin1Char(';'), 1, 1));
|
||||
}
|
||||
if (d->exec() == QDialog::Accepted) {
|
||||
m_configGroup->writeEntry(pname->text(), pparams->toPlainText() + ';' + pext->text());
|
||||
m_configGroup->writeEntry(pname->text(), pparams->toPlainText() + QLatin1Char(';') + pext->text());
|
||||
slotLoadProfiles();
|
||||
}
|
||||
delete d;
|
||||
@@ -178,13 +178,13 @@ void EncodingProfilesDialog::slotEditProfile()
|
||||
QListWidgetItem *item = profile_list->currentItem();
|
||||
if (item) {
|
||||
pname->setText(item->text());
|
||||
QString data = item->data(Qt::UserRole).toString();
|
||||
pparams->setPlainText(data.section(';', 0, 0));
|
||||
pext->setText(data.section(';', 1, 1));
|
||||
QString profilestr = item->data(Qt::UserRole).toString();
|
||||
pparams->setPlainText(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
pext->setText(profilestr.section(QLatin1Char(';'), 1, 1));
|
||||
pparams->setFocus();
|
||||
}
|
||||
if (d->exec() == QDialog::Accepted) {
|
||||
m_configGroup->writeEntry(pname->text(), pparams->toPlainText().simplified() + ';' + pext->text());
|
||||
m_configGroup->writeEntry(pname->text(), pparams->toPlainText().simplified() + QLatin1Char(';') + pext->text());
|
||||
slotLoadProfiles();
|
||||
}
|
||||
delete d;
|
||||
|
||||
@@ -30,7 +30,7 @@ class EncodingProfilesDialog : public QDialog, Ui::ManageEncodingProfile_UI
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EncodingProfilesDialog(int profileType, QWidget *parent = Q_NULLPTR);
|
||||
explicit EncodingProfilesDialog(int profileType, QWidget *parent = nullptr);
|
||||
~EncodingProfilesDialog();
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "utils/KoIconUtils.h"
|
||||
#include "dialogs/profilesdialog.h"
|
||||
#include "kdenlivesettings.h"
|
||||
#include "clipcreationdialog.h"
|
||||
#include "renderer.h"
|
||||
|
||||
#ifdef USE_V4L
|
||||
@@ -37,6 +38,7 @@
|
||||
#include <KRun>
|
||||
#include <KOpenWithDialog>
|
||||
#include "kdenlive_debug.h"
|
||||
#include <QAction>
|
||||
#include <QDir>
|
||||
#include <QTimer>
|
||||
#include <QThread>
|
||||
@@ -77,8 +79,10 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(const QMap<QString, QString> &map
|
||||
m_pw = new ProfileWidget(this);
|
||||
vbox->addWidget(m_pw);
|
||||
m_configProject.profile_box->setLayout(vbox);
|
||||
m_configProject.profile_box->setTitle(i18n("Select the default profile (preset)"));
|
||||
// Select profile
|
||||
m_pw->loadProfile(KdenliveSettings::default_profile().isEmpty() ? KdenliveSettings::current_profile() : KdenliveSettings::default_profile());
|
||||
connect(m_pw, &ProfileWidget::profileChanged, this, &KdenliveSettingsDialog::slotDialogModified);
|
||||
m_page8->setIcon(KoIconUtils::themedIcon(QStringLiteral("project-defaults")));
|
||||
connect(m_configProject.kcfg_generateproxy, &QAbstractButton::toggled, m_configProject.kcfg_proxyminsize, &QWidget::setEnabled);
|
||||
m_configProject.kcfg_proxyminsize->setEnabled(KdenliveSettings::generateproxy());
|
||||
@@ -115,6 +119,11 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(const QMap<QString, QString> &map
|
||||
m_configEnv.kcfg_librarytodefaultfolder->setToolTip(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/library"));
|
||||
connect(m_configEnv.kcfg_librarytodefaultfolder, &QAbstractButton::clicked, this, &KdenliveSettingsDialog::slotEnableLibraryFolder);
|
||||
|
||||
// Mime types
|
||||
QStringList mimes = ClipCreationDialog::getExtensions();
|
||||
qSort(mimes);
|
||||
m_configEnv.supportedmimes->setPlainText(mimes.join(QLatin1Char(' ')));
|
||||
|
||||
m_page2 = addPage(p2, i18n("Environment"));
|
||||
m_page2->setIcon(KoIconUtils::themedIcon(QStringLiteral("application-x-executable-script")));
|
||||
|
||||
@@ -335,7 +344,7 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(const QMap<QString, QString> &map
|
||||
if (versionCheck->waitForFinished()) {
|
||||
QString version = QString(versionCheck->readAll()).simplified();
|
||||
if (version.contains(QLatin1Char(' '))) {
|
||||
version = version.section(' ', -1);
|
||||
version = version.section(QLatin1Char(' '), -1);
|
||||
}
|
||||
dvgrabVersion = version.toDouble();
|
||||
|
||||
@@ -507,12 +516,12 @@ void KdenliveSettingsDialog::initDevices()
|
||||
QString deviceId;
|
||||
while (!line.isNull()) {
|
||||
if (line.contains(QStringLiteral("playback"))) {
|
||||
deviceId = line.section(':', 0, 0);
|
||||
m_configSdl.kcfg_audio_device->addItem(line.section(':', 1, 1), "plughw:" + QString::number(deviceId.section('-', 0, 0).toInt()) + ',' + QString::number(deviceId.section('-', 1, 1).toInt()));
|
||||
deviceId = line.section(QLatin1Char(':'), 0, 0);
|
||||
m_configSdl.kcfg_audio_device->addItem(line.section(QLatin1Char(':'), 1, 1), "plughw:" + QString::number(deviceId.section(QLatin1Char('-'), 0, 0).toInt()) + QLatin1Char(',') + QString::number(deviceId.section(QLatin1Char('-'), 1, 1).toInt()));
|
||||
}
|
||||
if (line.contains(QStringLiteral("capture"))) {
|
||||
deviceId = line.section(':', 0, 0);
|
||||
m_configCapture.kcfg_v4l_alsadevice->addItem(line.section(':', 1, 1).simplified(), "hw:" + QString::number(deviceId.section('-', 0, 0).toInt()) + ',' + QString::number(deviceId.section('-', 1, 1).toInt()));
|
||||
deviceId = line.section(QLatin1Char(':'), 0, 0);
|
||||
m_configCapture.kcfg_v4l_alsadevice->addItem(line.section(QLatin1Char(':'), 1, 1).simplified(), "hw:" + QString::number(deviceId.section(QLatin1Char('-'), 0, 0).toInt()) + QLatin1Char(',') + QString::number(deviceId.section(QLatin1Char('-'), 1, 1).toInt()));
|
||||
}
|
||||
line = stream.readLine();
|
||||
}
|
||||
@@ -539,7 +548,7 @@ void KdenliveSettingsDialog::initDevices()
|
||||
KdenliveSettings::setV4l_alsadevice(ix);
|
||||
}
|
||||
|
||||
m_configSdl.kcfg_audio_backend->addItem(i18n("SDL"), "sdl_audio");
|
||||
m_configSdl.kcfg_audio_backend->addItem(i18n("SDL"), KdenliveSettings::sdlAudioBackend());
|
||||
m_configSdl.kcfg_audio_backend->addItem(i18n("RtAudio"), "rtaudio");
|
||||
|
||||
if (!KdenliveSettings::audiobackend().isEmpty()) {
|
||||
@@ -547,7 +556,7 @@ void KdenliveSettingsDialog::initDevices()
|
||||
m_configSdl.kcfg_audio_backend->setCurrentIndex(ix);
|
||||
KdenliveSettings::setAudio_backend(ix);
|
||||
}
|
||||
m_configSdl.group_sdl->setEnabled(KdenliveSettings::audiobackend() == QLatin1String("sdl_audio"));
|
||||
m_configSdl.group_sdl->setEnabled(KdenliveSettings::audiobackend().startsWith(QLatin1String("sdl")));
|
||||
|
||||
loadCurrentV4lProfileInfo();
|
||||
}
|
||||
@@ -557,14 +566,14 @@ void KdenliveSettingsDialog::slotReadAudioDevices()
|
||||
QString result = QString(m_readProcess.readAllStandardOutput());
|
||||
//qCDebug(KDENLIVE_LOG) << "// / / / / / READING APLAY: ";
|
||||
//qCDebug(KDENLIVE_LOG) << result;
|
||||
const QStringList lines = result.split('\n');
|
||||
for (const QString &data : lines) {
|
||||
const QStringList lines = result.split(QLatin1Char('\n'));
|
||||
for (const QString &devicestr : lines) {
|
||||
////qCDebug(KDENLIVE_LOG) << "// READING LINE: " << data;
|
||||
if (!data.startsWith(' ') && data.count(':') > 1) {
|
||||
QString card = data.section(':', 0, 0).section(' ', -1);
|
||||
QString device = data.section(':', 1, 1).section(' ', -1);
|
||||
m_configSdl.kcfg_audio_device->addItem(data.section(':', -1).simplified(), "plughw:" + card + ',' + device);
|
||||
m_configCapture.kcfg_v4l_alsadevice->addItem(data.section(':', -1).simplified(), "hw:" + card + ',' + device);
|
||||
if (!devicestr.startsWith(QLatin1Char(' ')) && devicestr.count(QLatin1Char(':')) > 1) {
|
||||
QString card = devicestr.section(QLatin1Char(':'), 0, 0).section(QLatin1Char(' '), -1);
|
||||
QString device = devicestr.section(QLatin1Char(':'), 1, 1).section(QLatin1Char(' '), -1);
|
||||
m_configSdl.kcfg_audio_device->addItem(devicestr.section(QLatin1Char(':'), -1).simplified(), "plughw:" + card + QLatin1Char(',') + device);
|
||||
m_configCapture.kcfg_v4l_alsadevice->addItem(devicestr.section(QLatin1Char(':'), -1).simplified(), "hw:" + card + QLatin1Char(',') + device);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -692,10 +701,23 @@ void KdenliveSettingsDialog::updateWidgets()
|
||||
#endif /* USE_JOGSHUTTLE */
|
||||
}
|
||||
|
||||
void KdenliveSettingsDialog::accept()
|
||||
{
|
||||
if (m_pw->selectedProfile().isEmpty()) {
|
||||
KMessageBox::error(this, i18n("Please select a video profile"));
|
||||
return;
|
||||
}
|
||||
KConfigDialog::accept();
|
||||
}
|
||||
|
||||
void KdenliveSettingsDialog::updateSettings()
|
||||
{
|
||||
// Save changes to settings (for example when user pressed "Apply" or "Ok")
|
||||
// //qCDebug(KDENLIVE_LOG) << "// // // KCONFIG UPDATE called";
|
||||
if (m_pw->selectedProfile().isEmpty()) {
|
||||
KMessageBox::error(this, i18n("Please select a video profile"));
|
||||
return;
|
||||
}
|
||||
KdenliveSettings::setDefault_profile(m_pw->selectedProfile());
|
||||
|
||||
bool resetProfile = false;
|
||||
@@ -740,54 +762,54 @@ void KdenliveSettingsDialog::updateSettings()
|
||||
updateCapturePath = true;
|
||||
}
|
||||
|
||||
if ((uint) m_configCapture.kcfg_firewireformat->currentIndex() != KdenliveSettings::firewireformat()) {
|
||||
if (m_configCapture.kcfg_firewireformat->currentIndex() != KdenliveSettings::firewireformat()) {
|
||||
KdenliveSettings::setFirewireformat(m_configCapture.kcfg_firewireformat->currentIndex());
|
||||
updateCapturePath = true;
|
||||
}
|
||||
|
||||
if ((uint) m_configCapture.kcfg_v4l_format->currentIndex() != KdenliveSettings::v4l_format()) {
|
||||
if (m_configCapture.kcfg_v4l_format->currentIndex() != KdenliveSettings::v4l_format()) {
|
||||
saveCurrentV4lProfile();
|
||||
KdenliveSettings::setV4l_format(0);
|
||||
}
|
||||
|
||||
// Check if screengrab is fullscreen
|
||||
if ((uint) m_configCapture.kcfg_grab_capture_type->currentIndex() != KdenliveSettings::grab_capture_type()) {
|
||||
if (m_configCapture.kcfg_grab_capture_type->currentIndex() != KdenliveSettings::grab_capture_type()) {
|
||||
KdenliveSettings::setGrab_capture_type(m_configCapture.kcfg_grab_capture_type->currentIndex());
|
||||
emit updateFullScreenGrab();
|
||||
}
|
||||
|
||||
// Check encoding profiles
|
||||
// FFmpeg
|
||||
QString data = m_configCapture.kcfg_v4l_profile->itemData(m_configCapture.kcfg_v4l_profile->currentIndex()).toString();
|
||||
if (!data.isEmpty() && (data.section(';', 0, 0) != KdenliveSettings::v4l_parameters() || data.section(';', 1, 1) != KdenliveSettings::v4l_extension())) {
|
||||
KdenliveSettings::setV4l_parameters(data.section(';', 0, 0));
|
||||
KdenliveSettings::setV4l_extension(data.section(';', 1, 1));
|
||||
QString profilestr = m_configCapture.kcfg_v4l_profile->itemData(m_configCapture.kcfg_v4l_profile->currentIndex()).toString();
|
||||
if (!profilestr.isEmpty() && (profilestr.section(QLatin1Char(';'), 0, 0) != KdenliveSettings::v4l_parameters() || profilestr.section(QLatin1Char(';'), 1, 1) != KdenliveSettings::v4l_extension())) {
|
||||
KdenliveSettings::setV4l_parameters(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
KdenliveSettings::setV4l_extension(profilestr.section(QLatin1Char(';'), 1, 1));
|
||||
}
|
||||
// screengrab
|
||||
data = m_configCapture.kcfg_grab_profile->itemData(m_configCapture.kcfg_grab_profile->currentIndex()).toString();
|
||||
if (!data.isEmpty() && (data.section(';', 0, 0) != KdenliveSettings::grab_parameters() || data.section(';', 1, 1) != KdenliveSettings::grab_extension())) {
|
||||
KdenliveSettings::setGrab_parameters(data.section(';', 0, 0));
|
||||
KdenliveSettings::setGrab_extension(data.section(';', 1, 1));
|
||||
profilestr = m_configCapture.kcfg_grab_profile->itemData(m_configCapture.kcfg_grab_profile->currentIndex()).toString();
|
||||
if (!profilestr.isEmpty() && (profilestr.section(QLatin1Char(';'), 0, 0) != KdenliveSettings::grab_parameters() || profilestr.section(QLatin1Char(';'), 1, 1) != KdenliveSettings::grab_extension())) {
|
||||
KdenliveSettings::setGrab_parameters(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
KdenliveSettings::setGrab_extension(profilestr.section(QLatin1Char(';'), 1, 1));
|
||||
}
|
||||
|
||||
// decklink
|
||||
data = m_configCapture.kcfg_decklink_profile->itemData(m_configCapture.kcfg_decklink_profile->currentIndex()).toString();
|
||||
if (!data.isEmpty() && (data.section(';', 0, 0) != KdenliveSettings::decklink_parameters() || data.section(';', 1, 1) != KdenliveSettings::decklink_extension())) {
|
||||
KdenliveSettings::setDecklink_parameters(data.section(';', 0, 0));
|
||||
KdenliveSettings::setDecklink_extension(data.section(';', 1, 1));
|
||||
profilestr = m_configCapture.kcfg_decklink_profile->itemData(m_configCapture.kcfg_decklink_profile->currentIndex()).toString();
|
||||
if (!profilestr.isEmpty() && (profilestr.section(QLatin1Char(';'), 0, 0) != KdenliveSettings::decklink_parameters() || profilestr.section(QLatin1Char(';'), 1, 1) != KdenliveSettings::decklink_extension())) {
|
||||
KdenliveSettings::setDecklink_parameters(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
KdenliveSettings::setDecklink_extension(profilestr.section(QLatin1Char(';'), 1, 1));
|
||||
}
|
||||
// proxies
|
||||
data = m_configProject.kcfg_proxy_profile->itemData(m_configProject.kcfg_proxy_profile->currentIndex()).toString();
|
||||
if (!data.isEmpty() && (data.section(';', 0, 0) != KdenliveSettings::proxyparams() || data.section(';', 1, 1) != KdenliveSettings::proxyextension())) {
|
||||
KdenliveSettings::setProxyparams(data.section(';', 0, 0));
|
||||
KdenliveSettings::setProxyextension(data.section(';', 1, 1));
|
||||
profilestr = m_configProject.kcfg_proxy_profile->itemData(m_configProject.kcfg_proxy_profile->currentIndex()).toString();
|
||||
if (!profilestr.isEmpty() && (profilestr.section(QLatin1Char(';'), 0, 0) != KdenliveSettings::proxyparams() || profilestr.section(QLatin1Char(';'), 1, 1) != KdenliveSettings::proxyextension())) {
|
||||
KdenliveSettings::setProxyparams(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
KdenliveSettings::setProxyextension(profilestr.section(QLatin1Char(';'), 1, 1));
|
||||
}
|
||||
|
||||
// timeline preview
|
||||
data = m_configProject.kcfg_preview_profile->itemData(m_configProject.kcfg_preview_profile->currentIndex()).toString();
|
||||
if (!data.isEmpty() && (data.section(';', 0, 0) != KdenliveSettings::previewparams() || data.section(';', 1, 1) != KdenliveSettings::previewextension())) {
|
||||
KdenliveSettings::setPreviewparams(data.section(';', 0, 0));
|
||||
KdenliveSettings::setPreviewextension(data.section(';', 1, 1));
|
||||
profilestr = m_configProject.kcfg_preview_profile->itemData(m_configProject.kcfg_preview_profile->currentIndex()).toString();
|
||||
if (!profilestr.isEmpty() && (profilestr.section(QLatin1Char(';'), 0, 0) != KdenliveSettings::previewparams() || profilestr.section(QLatin1Char(';'), 1, 1) != KdenliveSettings::previewextension())) {
|
||||
KdenliveSettings::setPreviewparams(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
KdenliveSettings::setPreviewextension(profilestr.section(QLatin1Char(';'), 1, 1));
|
||||
}
|
||||
|
||||
if (updateCapturePath) {
|
||||
@@ -876,6 +898,15 @@ void KdenliveSettingsDialog::updateSettings()
|
||||
}
|
||||
}
|
||||
|
||||
// Mimes
|
||||
if (m_configEnv.kcfg_addedExtensions->text() != KdenliveSettings::addedExtensions()) {
|
||||
// Update list
|
||||
KdenliveSettings::setAddedExtensions(m_configEnv.kcfg_addedExtensions->text());
|
||||
QStringList mimes = ClipCreationDialog::getExtensions();
|
||||
qSort(mimes);
|
||||
m_configEnv.supportedmimes->setPlainText(mimes.join(QLatin1Char(' ')));
|
||||
}
|
||||
|
||||
KConfigDialog::settingsChangedSlot();
|
||||
//KConfigDialog::updateSettings();
|
||||
if (resetProfile) {
|
||||
@@ -896,7 +927,7 @@ void KdenliveSettingsDialog::slotCheckAlsaDriver()
|
||||
void KdenliveSettingsDialog::slotCheckAudioBackend()
|
||||
{
|
||||
QString value = m_configSdl.kcfg_audio_backend->itemData(m_configSdl.kcfg_audio_backend->currentIndex()).toString();
|
||||
m_configSdl.group_sdl->setEnabled(value == QLatin1String("sdl_audio"));
|
||||
m_configSdl.group_sdl->setEnabled(value.startsWith(QLatin1String("sdl_audio")));
|
||||
}
|
||||
|
||||
void KdenliveSettingsDialog::loadTranscodeProfiles()
|
||||
@@ -911,11 +942,11 @@ void KdenliveSettingsDialog::loadTranscodeProfiles()
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
QListWidgetItem *item = new QListWidgetItem(i.key());
|
||||
QString data = i.value();
|
||||
if (data.contains(QLatin1Char(';'))) {
|
||||
item->setToolTip(data.section(';', 1, 1));
|
||||
QString profilestr = i.value();
|
||||
if (profilestr.contains(QLatin1Char(';'))) {
|
||||
item->setToolTip(profilestr.section(QLatin1Char(';'), 1, 1));
|
||||
}
|
||||
item->setData(Qt::UserRole, data);
|
||||
item->setData(Qt::UserRole, profilestr);
|
||||
m_configTranscode.profiles_list->addItem(item);
|
||||
//item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
||||
}
|
||||
@@ -925,7 +956,7 @@ void KdenliveSettingsDialog::loadTranscodeProfiles()
|
||||
|
||||
void KdenliveSettingsDialog::saveTranscodeProfiles()
|
||||
{
|
||||
QString transcodeFile = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/kdenlivetranscodingrc";
|
||||
QString transcodeFile = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/kdenlivetranscodingrc");
|
||||
KSharedConfigPtr config = KSharedConfig::openConfig(transcodeFile);
|
||||
KConfigGroup transConfig(config, "Transcoding");
|
||||
// read the entries
|
||||
@@ -945,16 +976,16 @@ void KdenliveSettingsDialog::slotAddTranscode()
|
||||
return;
|
||||
}
|
||||
QListWidgetItem *item = new QListWidgetItem(m_configTranscode.profile_name->text());
|
||||
QString data = m_configTranscode.profile_parameters->toPlainText();
|
||||
data.append(" %1." + m_configTranscode.profile_extension->text());
|
||||
data.append(';');
|
||||
QString profilestr = m_configTranscode.profile_parameters->toPlainText();
|
||||
profilestr.append(" %1." + m_configTranscode.profile_extension->text());
|
||||
profilestr.append(';');
|
||||
if (!m_configTranscode.profile_description->text().isEmpty()) {
|
||||
data.append(m_configTranscode.profile_description->text());
|
||||
profilestr.append(m_configTranscode.profile_description->text());
|
||||
}
|
||||
if (m_configTranscode.profile_audioonly->isChecked()) {
|
||||
data.append(";audio");
|
||||
profilestr.append(";audio");
|
||||
}
|
||||
item->setData(Qt::UserRole, data);
|
||||
item->setData(Qt::UserRole, profilestr);
|
||||
m_configTranscode.profiles_list->addItem(item);
|
||||
m_configTranscode.profiles_list->setCurrentItem(item);
|
||||
slotDialogModified();
|
||||
@@ -968,16 +999,16 @@ void KdenliveSettingsDialog::slotUpdateTranscodingProfile()
|
||||
}
|
||||
m_configTranscode.button_update->setEnabled(false);
|
||||
item->setText(m_configTranscode.profile_name->text());
|
||||
QString data = m_configTranscode.profile_parameters->toPlainText();
|
||||
data.append(" %1." + m_configTranscode.profile_extension->text());
|
||||
data.append(';');
|
||||
QString profilestr = m_configTranscode.profile_parameters->toPlainText();
|
||||
profilestr.append(" %1." + m_configTranscode.profile_extension->text());
|
||||
profilestr.append(';');
|
||||
if (!m_configTranscode.profile_description->text().isEmpty()) {
|
||||
data.append(m_configTranscode.profile_description->text());
|
||||
profilestr.append(m_configTranscode.profile_description->text());
|
||||
}
|
||||
if (m_configTranscode.profile_audioonly->isChecked()) {
|
||||
data.append(";audio");
|
||||
profilestr.append(QStringLiteral(";audio"));
|
||||
}
|
||||
item->setData(Qt::UserRole, data);
|
||||
item->setData(Qt::UserRole, profilestr);
|
||||
slotDialogModified();
|
||||
}
|
||||
|
||||
@@ -1017,16 +1048,16 @@ void KdenliveSettingsDialog::slotSetTranscodeProfile()
|
||||
return;
|
||||
}
|
||||
m_configTranscode.profile_name->setText(item->text());
|
||||
QString data = item->data(Qt::UserRole).toString();
|
||||
if (data.contains(QLatin1Char(';'))) {
|
||||
m_configTranscode.profile_description->setText(data.section(';', 1, 1));
|
||||
if (data.section(';', 2, 2) == QLatin1String("audio")) {
|
||||
QString profilestr = item->data(Qt::UserRole).toString();
|
||||
if (profilestr.contains(QLatin1Char(';'))) {
|
||||
m_configTranscode.profile_description->setText(profilestr.section(QLatin1Char(';'), 1, 1));
|
||||
if (profilestr.section(QLatin1Char(';'), 2, 2) == QLatin1String("audio")) {
|
||||
m_configTranscode.profile_audioonly->setChecked(true);
|
||||
}
|
||||
data = data.section(';', 0, 0).simplified();
|
||||
profilestr = profilestr.section(QLatin1Char(';'), 0, 0).simplified();
|
||||
}
|
||||
m_configTranscode.profile_extension->setText(data.section('.', -1));
|
||||
m_configTranscode.profile_parameters->setPlainText(data.section(' ', 0, -2));
|
||||
m_configTranscode.profile_extension->setText(profilestr.section(QLatin1Char('.'), -1));
|
||||
m_configTranscode.profile_parameters->setPlainText(profilestr.section(QLatin1Char(' '), 0, -2));
|
||||
m_configTranscode.profile_box->setEnabled(true);
|
||||
}
|
||||
|
||||
@@ -1070,7 +1101,7 @@ void KdenliveSettingsDialog::slotUpdatev4lDevice()
|
||||
m_configCapture.kcfg_v4l_format->blockSignals(true);
|
||||
m_configCapture.kcfg_v4l_format->clear();
|
||||
|
||||
QString vl4ProfilePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/profiles/video4linux";
|
||||
QString vl4ProfilePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/profiles/video4linux");
|
||||
if (QFile::exists(vl4ProfilePath)) {
|
||||
m_configCapture.kcfg_v4l_format->addItem(i18n("Current settings"));
|
||||
}
|
||||
@@ -1080,14 +1111,14 @@ void KdenliveSettingsDialog::slotUpdatev4lDevice()
|
||||
QString pixelFormat;
|
||||
QStringList itemRates;
|
||||
for (int i = 0; i < pixelformats.count(); ++i) {
|
||||
QString format = pixelformats.at(i).section(':', 0, 0);
|
||||
QString format = pixelformats.at(i).section(QLatin1Char(':'), 0, 0);
|
||||
QStringList sizes = pixelformats.at(i).split(':', QString::SkipEmptyParts);
|
||||
pixelFormat = sizes.takeFirst();
|
||||
for (int j = 0; j < sizes.count(); ++j) {
|
||||
itemSize = sizes.at(j).section('=', 0, 0);
|
||||
itemRates = sizes.at(j).section('=', 1, 1).split(',', QString::SkipEmptyParts);
|
||||
itemSize = sizes.at(j).section(QLatin1Char('='), 0, 0);
|
||||
itemRates = sizes.at(j).section(QLatin1Char('='), 1, 1).split(QLatin1Char(','), QString::SkipEmptyParts);
|
||||
for (int k = 0; k < itemRates.count(); ++k) {
|
||||
m_configCapture.kcfg_v4l_format->addItem('[' + format + "] " + itemSize + " (" + itemRates.at(k) + ')', QStringList() << format << itemSize.section('x', 0, 0) << itemSize.section('x', 1, 1) << itemRates.at(k).section('/', 0, 0) << itemRates.at(k).section('/', 1, 1));
|
||||
m_configCapture.kcfg_v4l_format->addItem(QLatin1Char('[') + format + QStringLiteral("] ") + itemSize + QStringLiteral(" (") + itemRates.at(k) + QLatin1Char(')'), QStringList() << format << itemSize.section('x', 0, 0) << itemSize.section('x', 1, 1) << itemRates.at(k).section(QLatin1Char('/'), 0, 0) << itemRates.at(k).section(QLatin1Char('/'), 1, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1103,14 +1134,14 @@ void KdenliveSettingsDialog::slotUpdatev4lCaptureProfile()
|
||||
loadCurrentV4lProfileInfo();
|
||||
return;
|
||||
}
|
||||
m_configCapture.p_size->setText(info.at(1) + 'x' + info.at(2));
|
||||
m_configCapture.p_fps->setText(info.at(3) + '/' + info.at(4));
|
||||
m_configCapture.p_size->setText(info.at(1) + QLatin1Char('x') + info.at(2));
|
||||
m_configCapture.p_fps->setText(info.at(3) + QLatin1Char('/') + info.at(4));
|
||||
m_configCapture.p_aspect->setText(QStringLiteral("1/1"));
|
||||
m_configCapture.p_display->setText(info.at(1) + '/' + info.at(2));
|
||||
m_configCapture.p_display->setText(info.at(1) + QLatin1Char('/') + info.at(2));
|
||||
m_configCapture.p_colorspace->setText(ProfilesDialog::getColorspaceDescription(601));
|
||||
m_configCapture.p_progressive->setText(i18n("Progressive"));
|
||||
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/profiles/");
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/profiles/"));
|
||||
if (!dir.exists() || !dir.exists(QStringLiteral("video4linux"))) {
|
||||
saveCurrentV4lProfile();
|
||||
}
|
||||
@@ -1118,7 +1149,7 @@ void KdenliveSettingsDialog::slotUpdatev4lCaptureProfile()
|
||||
|
||||
void KdenliveSettingsDialog::loadCurrentV4lProfileInfo()
|
||||
{
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/profiles/");
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/profiles/"));
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(QStringLiteral("."));
|
||||
}
|
||||
@@ -1139,10 +1170,10 @@ void KdenliveSettingsDialog::loadCurrentV4lProfileInfo()
|
||||
} else {
|
||||
prof = ProfilesDialog::getVideoProfile(dir.absoluteFilePath(QStringLiteral("video4linux")));
|
||||
}
|
||||
m_configCapture.p_size->setText(QString::number(prof.width) + 'x' + QString::number(prof.height));
|
||||
m_configCapture.p_fps->setText(QString::number(prof.frame_rate_num) + '/' + QString::number(prof.frame_rate_den));
|
||||
m_configCapture.p_aspect->setText(QString::number(prof.sample_aspect_num) + '/' + QString::number(prof.sample_aspect_den));
|
||||
m_configCapture.p_display->setText(QString::number(prof.display_aspect_num) + '/' + QString::number(prof.display_aspect_den));
|
||||
m_configCapture.p_size->setText(QString::number(prof.width) + QLatin1Char('x') + QString::number(prof.height));
|
||||
m_configCapture.p_fps->setText(QString::number(prof.frame_rate_num) + QLatin1Char('/') + QString::number(prof.frame_rate_den));
|
||||
m_configCapture.p_aspect->setText(QString::number(prof.sample_aspect_num) + QLatin1Char('/') + QString::number(prof.sample_aspect_den));
|
||||
m_configCapture.p_display->setText(QString::number(prof.display_aspect_num) + QLatin1Char('/') + QString::number(prof.display_aspect_den));
|
||||
m_configCapture.p_colorspace->setText(ProfilesDialog::getColorspaceDescription(prof.colorspace));
|
||||
if (prof.progressive) {
|
||||
m_configCapture.p_progressive->setText(i18n("Progressive"));
|
||||
@@ -1156,14 +1187,14 @@ void KdenliveSettingsDialog::saveCurrentV4lProfile()
|
||||
profile.colorspace = ProfilesDialog::getColorspaceFromDescription(m_configCapture.p_colorspace->text());
|
||||
profile.width = m_configCapture.p_size->text().section('x', 0, 0).toInt();
|
||||
profile.height = m_configCapture.p_size->text().section('x', 1, 1).toInt();
|
||||
profile.sample_aspect_num = m_configCapture.p_aspect->text().section('/', 0, 0).toInt();
|
||||
profile.sample_aspect_den = m_configCapture.p_aspect->text().section('/', 1, 1).toInt();
|
||||
profile.display_aspect_num = m_configCapture.p_display->text().section('/', 0, 0).toInt();
|
||||
profile.display_aspect_den = m_configCapture.p_display->text().section('/', 1, 1).toInt();
|
||||
profile.frame_rate_num = m_configCapture.p_fps->text().section('/', 0, 0).toInt();
|
||||
profile.frame_rate_den = m_configCapture.p_fps->text().section('/', 1, 1).toInt();
|
||||
profile.sample_aspect_num = m_configCapture.p_aspect->text().section(QLatin1Char('/'), 0, 0).toInt();
|
||||
profile.sample_aspect_den = m_configCapture.p_aspect->text().section(QLatin1Char('/'), 1, 1).toInt();
|
||||
profile.display_aspect_num = m_configCapture.p_display->text().section(QLatin1Char('/'), 0, 0).toInt();
|
||||
profile.display_aspect_den = m_configCapture.p_display->text().section(QLatin1Char('/'), 1, 1).toInt();
|
||||
profile.frame_rate_num = m_configCapture.p_fps->text().section(QLatin1Char('/'), 0, 0).toInt();
|
||||
profile.frame_rate_den = m_configCapture.p_fps->text().section(QLatin1Char('/'), 1, 1).toInt();
|
||||
profile.progressive = m_configCapture.p_progressive->text() == i18n("Progressive");
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/profiles/");
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/profiles/"));
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(QStringLiteral("."));
|
||||
}
|
||||
@@ -1177,9 +1208,9 @@ void KdenliveSettingsDialog::slotManageEncodingProfile()
|
||||
if (act) {
|
||||
type = act->data().toInt();
|
||||
}
|
||||
QPointer<EncodingProfilesDialog> d = new EncodingProfilesDialog(type);
|
||||
d->exec();
|
||||
delete d;
|
||||
QPointer<EncodingProfilesDialog> dia = new EncodingProfilesDialog(type);
|
||||
dia->exec();
|
||||
delete dia;
|
||||
loadEncodingProfiles();
|
||||
}
|
||||
|
||||
@@ -1259,11 +1290,11 @@ void KdenliveSettingsDialog::loadEncodingProfiles()
|
||||
m_configProject.kcfg_preview_profile->setCurrentIndex(m_configProject.kcfg_preview_profile->findText(currentItem));
|
||||
}
|
||||
m_configProject.kcfg_preview_profile->blockSignals(false);
|
||||
QString data = m_configProject.kcfg_preview_profile->itemData(m_configProject.kcfg_preview_profile->currentIndex()).toString();
|
||||
if (data.isEmpty()) {
|
||||
QString profilestr = m_configProject.kcfg_preview_profile->itemData(m_configProject.kcfg_preview_profile->currentIndex()).toString();
|
||||
if (profilestr.isEmpty()) {
|
||||
m_configProject.previewparams->clear();
|
||||
} else {
|
||||
m_configProject.previewparams->setPlainText(data.section(';', 0, 0));
|
||||
m_configProject.previewparams->setPlainText(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
}
|
||||
|
||||
// Load Proxy profiles
|
||||
@@ -1283,11 +1314,11 @@ void KdenliveSettingsDialog::loadEncodingProfiles()
|
||||
m_configProject.kcfg_proxy_profile->setCurrentIndex(m_configProject.kcfg_proxy_profile->findText(currentItem));
|
||||
}
|
||||
m_configProject.kcfg_proxy_profile->blockSignals(false);
|
||||
data = m_configProject.kcfg_proxy_profile->itemData(m_configProject.kcfg_proxy_profile->currentIndex()).toString();
|
||||
if (data.isEmpty()) {
|
||||
profilestr = m_configProject.kcfg_proxy_profile->itemData(m_configProject.kcfg_proxy_profile->currentIndex()).toString();
|
||||
if (profilestr.isEmpty()) {
|
||||
m_configProject.proxyparams->clear();
|
||||
} else {
|
||||
m_configProject.proxyparams->setPlainText(data.section(';', 0, 0));
|
||||
m_configProject.proxyparams->setPlainText(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1298,11 +1329,11 @@ void KdenliveSettingsDialog::slotUpdateDecklinkProfile(int ix)
|
||||
} else {
|
||||
ix = m_configCapture.kcfg_decklink_profile->currentIndex();
|
||||
}
|
||||
QString data = m_configCapture.kcfg_decklink_profile->itemData(ix).toString();
|
||||
if (data.isEmpty()) {
|
||||
QString profilestr = m_configCapture.kcfg_decklink_profile->itemData(ix).toString();
|
||||
if (profilestr.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_configCapture.decklink_parameters->setPlainText(data.section(';', 0, 0));
|
||||
m_configCapture.decklink_parameters->setPlainText(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
//
|
||||
}
|
||||
|
||||
@@ -1313,11 +1344,11 @@ void KdenliveSettingsDialog::slotUpdateV4lProfile(int ix)
|
||||
} else {
|
||||
ix = m_configCapture.kcfg_v4l_profile->currentIndex();
|
||||
}
|
||||
QString data = m_configCapture.kcfg_v4l_profile->itemData(ix).toString();
|
||||
if (data.isEmpty()) {
|
||||
QString profilestr = m_configCapture.kcfg_v4l_profile->itemData(ix).toString();
|
||||
if (profilestr.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_configCapture.v4l_parameters->setPlainText(data.section(';', 0, 0));
|
||||
m_configCapture.v4l_parameters->setPlainText(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
//
|
||||
}
|
||||
|
||||
@@ -1328,11 +1359,11 @@ void KdenliveSettingsDialog::slotUpdateGrabProfile(int ix)
|
||||
} else {
|
||||
ix = m_configCapture.kcfg_grab_profile->currentIndex();
|
||||
}
|
||||
QString data = m_configCapture.kcfg_grab_profile->itemData(ix).toString();
|
||||
if (data.isEmpty()) {
|
||||
QString profilestr = m_configCapture.kcfg_grab_profile->itemData(ix).toString();
|
||||
if (profilestr.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_configCapture.grab_parameters->setPlainText(data.section(';', 0, 0));
|
||||
m_configCapture.grab_parameters->setPlainText(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
//
|
||||
}
|
||||
|
||||
@@ -1343,11 +1374,11 @@ void KdenliveSettingsDialog::slotUpdateProxyProfile(int ix)
|
||||
} else {
|
||||
ix = m_configProject.kcfg_proxy_profile->currentIndex();
|
||||
}
|
||||
QString data = m_configProject.kcfg_proxy_profile->itemData(ix).toString();
|
||||
if (data.isEmpty()) {
|
||||
QString profilestr = m_configProject.kcfg_proxy_profile->itemData(ix).toString();
|
||||
if (profilestr.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_configProject.proxyparams->setPlainText(data.section(';', 0, 0));
|
||||
m_configProject.proxyparams->setPlainText(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
}
|
||||
|
||||
void KdenliveSettingsDialog::slotUpdatePreviewProfile(int ix)
|
||||
@@ -1357,16 +1388,16 @@ void KdenliveSettingsDialog::slotUpdatePreviewProfile(int ix)
|
||||
} else {
|
||||
ix = m_configProject.kcfg_preview_profile->currentIndex();
|
||||
}
|
||||
QString data = m_configProject.kcfg_preview_profile->itemData(ix).toString();
|
||||
if (data.isEmpty()) {
|
||||
QString profilestr = m_configProject.kcfg_preview_profile->itemData(ix).toString();
|
||||
if (profilestr.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_configProject.previewparams->setPlainText(data.section(';', 0, 0));
|
||||
m_configProject.previewparams->setPlainText(profilestr.section(QLatin1Char(';'), 0, 0));
|
||||
}
|
||||
|
||||
void KdenliveSettingsDialog::slotEditVideo4LinuxProfile()
|
||||
{
|
||||
QString vl4ProfilePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/profiles/video4linux";
|
||||
QString vl4ProfilePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/profiles/video4linux");
|
||||
QPointer<ProfilesDialog> w = new ProfilesDialog(vl4ProfilePath, true);
|
||||
if (w->exec() == QDialog::Accepted) {
|
||||
// save and update profile
|
||||
|
||||
@@ -40,15 +40,16 @@ class KdenliveSettingsDialog : public KConfigDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KdenliveSettingsDialog(const QMap<QString, QString> &mappable_actions, bool gpuAllowed, QWidget *parent = Q_NULLPTR);
|
||||
KdenliveSettingsDialog(const QMap<QString, QString> &mappable_actions, bool gpuAllowed, QWidget *parent = nullptr);
|
||||
~KdenliveSettingsDialog();
|
||||
void showPage(int page, int option);
|
||||
void checkProfile();
|
||||
|
||||
protected slots:
|
||||
void updateSettings() Q_DECL_OVERRIDE;
|
||||
void updateWidgets() Q_DECL_OVERRIDE;
|
||||
bool hasChanged() Q_DECL_OVERRIDE;
|
||||
void updateSettings() override;
|
||||
void updateWidgets() override;
|
||||
bool hasChanged() override;
|
||||
void accept() override;
|
||||
|
||||
private slots:
|
||||
void slotCheckShuttle(int state = 0);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "profilesdialog.h"
|
||||
#include "kdenlivesettings.h"
|
||||
#include "utils/KoIconUtils.h"
|
||||
#include "profiles/profilerepository.hpp"
|
||||
|
||||
#include <KMessageBox>
|
||||
#include <KMessageWidget>
|
||||
@@ -35,6 +36,10 @@ ProfilesDialog::ProfilesDialog(const QString &profileDescription, QWidget *paren
|
||||
m_profileIsModified(false),
|
||||
m_isCustomProfile(false)
|
||||
{
|
||||
|
||||
//ask profile repository for a refresh
|
||||
ProfileRepository::get()->refresh();
|
||||
|
||||
m_view.setupUi(this);
|
||||
|
||||
// Add message widget
|
||||
@@ -157,13 +162,11 @@ void ProfilesDialog::slotProfileEdited()
|
||||
|
||||
void ProfilesDialog::fillList(const QString &selectedProfile)
|
||||
{
|
||||
// List the Mlt profiles
|
||||
m_view.profiles_list->clear();
|
||||
QMap<QString, QString> profilesInfo = ProfilesDialog::getProfilesInfo();
|
||||
QMapIterator<QString, QString> i(profilesInfo);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
m_view.profiles_list->addItem(i.value(), i.key());
|
||||
// Retrieve the list from the repository
|
||||
QVector<QPair<QString, QString> > profiles = ProfileRepository::get()->getAllProfiles();
|
||||
for (const auto & p : profiles) {
|
||||
m_view.profiles_list->addItem(p.first, p.second);
|
||||
}
|
||||
|
||||
if (!KdenliveSettings::default_profile().isEmpty()) {
|
||||
@@ -490,6 +493,9 @@ QList<MltVideoProfile> ProfilesDialog::profilesList()
|
||||
}
|
||||
|
||||
// Check custom profiles
|
||||
qDebug() << "searching custom in "<<QStandardPaths::AppDataLocation;
|
||||
qDebug() << "name" << QStandardPaths::displayName(QStandardPaths::AppDataLocation);
|
||||
qDebug() << "loc" << QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
|
||||
QStringList customProfiles = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, QStringLiteral("profiles/"), QStandardPaths::LocateDirectory);
|
||||
for (int i = 0; i < customProfiles.size(); ++i) {
|
||||
QDir customDir(customProfiles.at(i));
|
||||
@@ -506,39 +512,6 @@ QList<MltVideoProfile> ProfilesDialog::profilesList()
|
||||
return list;
|
||||
}
|
||||
|
||||
// static
|
||||
QMap<QString, QString> ProfilesDialog::getProfilesInfo()
|
||||
{
|
||||
QMap<QString, QString> result;
|
||||
QStringList profilesFilter;
|
||||
profilesFilter << QStringLiteral("*");
|
||||
|
||||
// List the Mlt profiles
|
||||
QDir mltDir(KdenliveSettings::mltpath());
|
||||
QStringList profilesFiles = mltDir.entryList(profilesFilter, QDir::Files);
|
||||
for (int i = 0; i < profilesFiles.size(); ++i) {
|
||||
KConfig confFile(mltDir.absoluteFilePath(profilesFiles.at(i)), KConfig::SimpleConfig);
|
||||
QString desc = confFile.entryMap().value(QStringLiteral("description"));
|
||||
if (!desc.isEmpty()) {
|
||||
result.insert(profilesFiles.at(i), desc);
|
||||
}
|
||||
}
|
||||
|
||||
// List custom profiles
|
||||
QStringList customProfiles = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, QStringLiteral("profiles/"), QStandardPaths::LocateDirectory);
|
||||
for (int i = 0; i < customProfiles.size(); ++i) {
|
||||
QDir profileDir(customProfiles.at(i));
|
||||
profilesFiles = profileDir.entryList(profilesFilter, QDir::Files);
|
||||
for (int j = 0; j < profilesFiles.size(); ++j) {
|
||||
KConfig confFile(profileDir.absoluteFilePath(profilesFiles.at(j)), KConfig::SimpleConfig);
|
||||
QString desc = confFile.entryMap().value(QStringLiteral("description"));
|
||||
if (!desc.isEmpty()) {
|
||||
result.insert(profileDir.absoluteFilePath(profilesFiles.at(j)), desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// static
|
||||
QMap< QString, QString > ProfilesDialog::getSettingsFromFile(const QString &path)
|
||||
@@ -724,8 +697,7 @@ int ProfilesDialog::getColorspaceFromDescription(const QString &description)
|
||||
//TODO: should the descriptions be translated?
|
||||
if (description == QLatin1String("SMPTE240M")) {
|
||||
return 240;
|
||||
}
|
||||
if (description == QLatin1String("ITU-R 709")) {
|
||||
} else if (description == QLatin1String("ITU-R 709")) {
|
||||
return 709;
|
||||
}
|
||||
return 601;
|
||||
|
||||
@@ -31,9 +31,9 @@ class ProfilesDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit ProfilesDialog(const QString &profileDescription = QString(), QWidget *parent = Q_NULLPTR);
|
||||
explicit ProfilesDialog(const QString &profileDescription = QString(), QWidget *parent = nullptr);
|
||||
/** @brief Using this constructor, the dialog only allows editing one profile. */
|
||||
explicit ProfilesDialog(const QString &profilePath, bool, QWidget *parent = Q_NULLPTR);
|
||||
explicit ProfilesDialog(const QString &profilePath, bool, QWidget *parent = nullptr);
|
||||
|
||||
void fillList(const QString &selectedProfile = QString());
|
||||
static QMap< QString, QString > getSettingsFromFile(const QString &path);
|
||||
@@ -41,7 +41,6 @@ public:
|
||||
static MltVideoProfile getVideoProfileFromXml(const QDomElement &element);
|
||||
static MltVideoProfile getVideoProfile(const QString &name);
|
||||
static MltVideoProfile getVideoProfile(Mlt::Profile &profile);
|
||||
static QMap<QString, QString> getProfilesInfo();
|
||||
static void saveProfile(MltVideoProfile &profile, QString profilePath = QString());
|
||||
/** @brief Check if a given profile has a profile file describing it */
|
||||
static QString existingProfile(const MltVideoProfile &profile);
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "timecode.h"
|
||||
#include "dialogs/profilesdialog.h"
|
||||
#include "utils/KoIconUtils.h"
|
||||
#include "profiles/profilerepository.hpp"
|
||||
#include "profiles/profilemodel.hpp"
|
||||
|
||||
#include "klocalizedstring.h"
|
||||
#include <KMessageBox>
|
||||
@@ -31,6 +33,8 @@
|
||||
#include <KNotification>
|
||||
#include <KMimeTypeTrader>
|
||||
#include <KIO/DesktopExecParser>
|
||||
#include <knotifications_version.h>
|
||||
#include <kio_version.h>
|
||||
|
||||
#include <qglobal.h>
|
||||
#include <qstring.h>
|
||||
@@ -42,7 +46,6 @@
|
||||
#include <QProcess>
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QThread>
|
||||
#include <QScriptEngine>
|
||||
#include <QKeyEvent>
|
||||
#include <QTimer>
|
||||
#include <QStandardPaths>
|
||||
@@ -89,6 +92,16 @@ enum JOBSTATUS {
|
||||
ABORTEDJOB
|
||||
};
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
const QLatin1String ScriptFormat(".bat");
|
||||
QString ScriptSetVar(const QString name, const QString value) { return QString("set ") + name + "=\"" + value + '\"'; }
|
||||
QString ScriptGetVar(const QString varName) { return QString('%') + varName + '%'; }
|
||||
#else
|
||||
const QLatin1String ScriptFormat(".sh");
|
||||
QString ScriptSetVar(const QString name, const QString value) { return name + "=\"" + value + '\"'; }
|
||||
QString ScriptGetVar(const QString varName) { return QString('$') + varName; }
|
||||
#endif
|
||||
|
||||
static QStringList acodecsList;
|
||||
static QStringList vcodecsList;
|
||||
static QStringList supportedFormats;
|
||||
@@ -146,7 +159,7 @@ const QString RenderJobItem::metadata() const
|
||||
return m_data;
|
||||
}
|
||||
|
||||
RenderWidget::RenderWidget(const QString &projectfolder, bool enableProxy, const MltVideoProfile &profile, QWidget *parent) :
|
||||
RenderWidget::RenderWidget(const QString &projectfolder, bool enableProxy, const QString &profile, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_projectFolder(projectfolder),
|
||||
m_profile(profile),
|
||||
@@ -239,7 +252,7 @@ RenderWidget::RenderWidget(const QString &projectfolder, bool enableProxy, const
|
||||
|
||||
connect(m_view.export_audio, &QCheckBox::stateChanged, this, &RenderWidget::slotUpdateAudioLabel);
|
||||
m_view.export_audio->setCheckState(Qt::PartiallyChecked);
|
||||
|
||||
checkCodecs();
|
||||
parseProfiles();
|
||||
parseScriptFiles();
|
||||
m_view.running_jobs->setUniformRowHeights(false);
|
||||
@@ -283,6 +296,12 @@ RenderWidget::RenderWidget(const QString &projectfolder, bool enableProxy, const
|
||||
//m_view.splitter->setStretchFactor(0, 2);
|
||||
|
||||
m_view.out_file->setMode(KFile::File);
|
||||
#if KIO_VERSION >= QT_VERSION_CHECK(5,33,0)
|
||||
m_view.out_file->setAcceptMode(QFileDialog::AcceptSave);
|
||||
#elif !defined(KIOWIDGETS_DEPRECATED)
|
||||
m_view.out_file->fileDialog()->setAcceptMode(QFileDialog::AcceptSave);
|
||||
#endif
|
||||
|
||||
m_view.out_file->setFocusPolicy(Qt::ClickFocus);
|
||||
|
||||
m_jobsDelegate = new RenderViewDelegate(this);
|
||||
@@ -318,7 +337,6 @@ RenderWidget::RenderWidget(const QString &projectfolder, bool enableProxy, const
|
||||
if (!interface || (!interface->isServiceRegistered(QStringLiteral("org.kde.ksmserver")) && !interface->isServiceRegistered(QStringLiteral("org.gnome.SessionManager")))) {
|
||||
m_view.shutdown->setEnabled(false);
|
||||
}
|
||||
checkCodecs();
|
||||
refreshView();
|
||||
focusFirstVisibleItem();
|
||||
adjustSize();
|
||||
@@ -408,14 +426,14 @@ void RenderWidget::setGuides(const QMap<double, QString> &guidesData, double dur
|
||||
m_view.render_guide->setEnabled(false);
|
||||
m_view.create_chapter->setEnabled(false);
|
||||
}
|
||||
double fps = (double) m_profile.frame_rate_num / m_profile.frame_rate_den;
|
||||
double fps = ProfileRepository::get()->getProfile(m_profile)->fps();
|
||||
QMapIterator<double, QString> i(guidesData);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
GenTime pos = GenTime(i.key());
|
||||
const QString guidePos = Timecode::getStringTimecode(pos.frames(fps), fps);
|
||||
m_view.guide_start->addItem(i.value() + '/' + guidePos, i.key());
|
||||
m_view.guide_end->addItem(i.value() + '/' + guidePos, i.key());
|
||||
m_view.guide_start->addItem(i.value() + QLatin1Char('/') + guidePos, i.key());
|
||||
m_view.guide_end->addItem(i.value() + QLatin1Char('/') + guidePos, i.key());
|
||||
}
|
||||
if (!guidesData.isEmpty()) {
|
||||
m_view.guide_end->addItem(i18n("End"), QString::number(duration));
|
||||
@@ -557,8 +575,9 @@ void RenderWidget::slotSaveProfile()
|
||||
profileElement.setAttribute(QStringLiteral("defaultaudioquality"), QString::number(ui.default_abitrate->value()));
|
||||
profileElement.setAttribute(QStringLiteral("audioqualities"), ui.abitrates_list->text());
|
||||
}
|
||||
if (!ui.speeds_list->toPlainText().isEmpty()) {
|
||||
profileElement.setAttribute(QStringLiteral("speeds"), ui.speeds_list->toPlainText().replace('\n', ';').simplified());
|
||||
QString speeds_list_str = ui.speeds_list->toPlainText();
|
||||
if (!speeds_list_str.isEmpty()) {
|
||||
profileElement.setAttribute(QStringLiteral("speeds"), speeds_list_str.replace('\n', ';').simplified());
|
||||
}
|
||||
|
||||
doc.appendChild(profileElement);
|
||||
@@ -571,7 +590,7 @@ void RenderWidget::slotSaveProfile()
|
||||
|
||||
bool RenderWidget::saveProfile(QDomElement newprofile)
|
||||
{
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/export/");
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/export/"));
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(QStringLiteral("."));
|
||||
}
|
||||
@@ -755,7 +774,7 @@ void RenderWidget::slotEditProfile()
|
||||
|
||||
if (d->exec() == QDialog::Accepted) {
|
||||
slotDeleteProfile(false);
|
||||
QString exportFile = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/export/customprofiles.xml";
|
||||
QString exportFile = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/export/customprofiles.xml");
|
||||
QDomDocument doc;
|
||||
QFile file(exportFile);
|
||||
doc.setContent(&file, false);
|
||||
@@ -827,9 +846,10 @@ void RenderWidget::slotEditProfile()
|
||||
profileElement.setAttribute(QStringLiteral("audioqualities"), ui.abitrates_list->text());
|
||||
}
|
||||
|
||||
if (!ui.speeds_list->toPlainText().isEmpty()) {
|
||||
QString speeds_list_str = ui.speeds_list->toPlainText();
|
||||
if (!speeds_list_str.isEmpty()) {
|
||||
// profile has a variable speed
|
||||
profileElement.setAttribute(QStringLiteral("speeds"), ui.speeds_list->toPlainText().replace('\n', ';').simplified());
|
||||
profileElement.setAttribute(QStringLiteral("speeds"), speeds_list_str.replace('\n', ';').simplified());
|
||||
}
|
||||
|
||||
profiles.appendChild(profileElement);
|
||||
@@ -873,7 +893,7 @@ void RenderWidget::slotDeleteProfile(bool refresh)
|
||||
}
|
||||
QString currentProfile = item->text(0);
|
||||
|
||||
QString exportFile = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/export/customprofiles.xml";
|
||||
QString exportFile = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/export/customprofiles.xml");
|
||||
QDomDocument doc;
|
||||
QFile file(exportFile);
|
||||
doc.setContent(&file, false);
|
||||
@@ -940,7 +960,7 @@ void RenderWidget::focusFirstVisibleItem(const QString &profile)
|
||||
if (!profile.isEmpty()) {
|
||||
QList<QTreeWidgetItem *> items = m_view.formats->findItems(profile, Qt::MatchExactly | Qt::MatchRecursive);
|
||||
if (!items.isEmpty()) {
|
||||
item = items.first();
|
||||
item = items.constFirst();
|
||||
}
|
||||
}
|
||||
if (!item) {
|
||||
@@ -969,7 +989,7 @@ void RenderWidget::slotPrepareExport(bool scriptExport, const QString &scriptPat
|
||||
}
|
||||
QString chapterFile;
|
||||
if (m_view.create_chapter->isChecked()) {
|
||||
chapterFile = m_view.out_file->url().toLocalFile() + ".dvdchapter";
|
||||
chapterFile = m_view.out_file->url().toLocalFile() + QStringLiteral(".dvdchapter");
|
||||
}
|
||||
|
||||
// mantisbt 1051
|
||||
@@ -1010,7 +1030,7 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
QFileInfo dfi(dest);
|
||||
QStringList filePath;
|
||||
// construct the full file path
|
||||
filePath << dfi.absolutePath() << QDir::separator() << dfi.completeBaseName() + "_" <<
|
||||
filePath << dfi.absolutePath() << QDir::separator() << dfi.completeBaseName() + QLatin1Char('_') <<
|
||||
QString(trackNames.at(stemIdx)).replace(QLatin1Char(' '), QLatin1Char('_')) << QStringLiteral(".") << dfi.suffix();
|
||||
dest = filePath.join(QString());
|
||||
}
|
||||
@@ -1028,8 +1048,8 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
imageSequences << QStringLiteral("jpg") << QStringLiteral("png") << QStringLiteral("bmp") << QStringLiteral("dpx") << QStringLiteral("ppm") << QStringLiteral("tga") << QStringLiteral("tif");
|
||||
if (imageSequences.contains(extension)) {
|
||||
// format string for counter?
|
||||
if (!QRegExp(".*%[0-9]*d.*").exactMatch(dest)) {
|
||||
dest = dest.section('.', 0, -2) + "_%05d." + extension;
|
||||
if (!QRegExp(QStringLiteral(".*%[0-9]*d.*")).exactMatch(dest)) {
|
||||
dest = dest.section(QLatin1Char('.'), 0, -2) + QStringLiteral("_%05d.") + extension;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1053,9 +1073,11 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
return;
|
||||
}
|
||||
QTextStream outStream(&file);
|
||||
#ifndef Q_OS_WIN
|
||||
outStream << "#! /bin/sh" << '\n' << '\n';
|
||||
outStream << "RENDERER=" << '\"' + m_renderer + '\"' << '\n';
|
||||
outStream << "MELT=" << '\"' + KdenliveSettings::rendererpath() + '\"' << "\n\n";
|
||||
#endif
|
||||
outStream << ScriptSetVar("RENDERER", m_renderer) << '\n';
|
||||
outStream << ScriptSetVar("MELT", KdenliveSettings::rendererpath()) << "\n\n";
|
||||
}
|
||||
|
||||
QStringList overlayargs;
|
||||
@@ -1071,12 +1093,13 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
if (!scriptExport) {
|
||||
render_process_args << QStringLiteral("-erase");
|
||||
}
|
||||
#ifndef Q_OS_WIN
|
||||
if (KdenliveSettings::usekuiserver()) {
|
||||
render_process_args << QStringLiteral("-kuiserver");
|
||||
}
|
||||
|
||||
// get process id
|
||||
render_process_args << QStringLiteral("-pid:%1").arg(QCoreApplication::applicationPid());
|
||||
#endif
|
||||
|
||||
// Set locale for render process if required
|
||||
if (QLocale().decimalPoint() != QLocale::system().decimalPoint()) {
|
||||
@@ -1094,58 +1117,58 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
// Check for fps change
|
||||
double forcedfps = 0;
|
||||
if (std.startsWith(QLatin1String("r="))) {
|
||||
QString sub = std.section(' ', 0, 0).toLower();
|
||||
sub = sub.section('=', 1, 1);
|
||||
QString sub = std.section(QLatin1Char(' '), 0, 0).toLower();
|
||||
sub = sub.section(QLatin1Char('='), 1, 1);
|
||||
forcedfps = sub.toDouble();
|
||||
} else if (std.contains(QStringLiteral(" r="))) {
|
||||
QString sub = std.section(QStringLiteral(" r="), 1, 1);
|
||||
sub = sub.section(' ', 0, 0).toLower();
|
||||
sub = sub.section(QLatin1Char(' '), 0, 0).toLower();
|
||||
forcedfps = sub.toDouble();
|
||||
} else if (std.contains(QStringLiteral("mlt_profile="))) {
|
||||
QString sub = std.section(QStringLiteral("mlt_profile="), 1, 1);
|
||||
sub = sub.section(' ', 0, 0).toLower();
|
||||
MltVideoProfile destinationProfile = ProfilesDialog::getVideoProfile(sub);
|
||||
forcedfps = (double) destinationProfile.frame_rate_num / destinationProfile.frame_rate_den;
|
||||
sub = sub.section(QLatin1Char(' '), 0, 0).toLower();
|
||||
forcedfps = ProfileRepository::get()->getProfile(sub)->fps();
|
||||
}
|
||||
|
||||
bool resizeProfile = false;
|
||||
std::unique_ptr<ProfileModel>& profile = ProfileRepository::get()->getProfile(m_profile);
|
||||
if (renderArgs.contains(QLatin1String("%dv_standard"))) {
|
||||
QString std;
|
||||
if (fmod((double)m_profile.frame_rate_num / m_profile.frame_rate_den, 30.01) > 27) {
|
||||
std = QStringLiteral("ntsc");
|
||||
if (!(m_profile.frame_rate_num == 30000 && m_profile.frame_rate_den == 1001)) {
|
||||
QString dvstd;
|
||||
if (fmod((double)profile->frame_rate_num() / profile->frame_rate_den(), 30.01) > 27) {
|
||||
dvstd = QStringLiteral("ntsc");
|
||||
if (!(profile->frame_rate_num() == 30000 && profile->frame_rate_den() == 1001)) {
|
||||
forcedfps = 30000.0 / 1001;
|
||||
}
|
||||
if (!(m_profile.width == 720 && m_profile.height == 480)) {
|
||||
if (!(profile->width() == 720 && profile->height() == 480)) {
|
||||
resizeProfile = true;
|
||||
}
|
||||
} else {
|
||||
std = QStringLiteral("pal");
|
||||
if (!(m_profile.frame_rate_num == 25 && m_profile.frame_rate_den == 1)) {
|
||||
dvstd = QStringLiteral("pal");
|
||||
if (!(profile->frame_rate_num() == 25 && profile->frame_rate_den() == 1)) {
|
||||
forcedfps = 25;
|
||||
}
|
||||
if (!(m_profile.width == 720 && m_profile.height == 576)) {
|
||||
if (!(profile->width() == 720 && profile->height() == 576)) {
|
||||
resizeProfile = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((double) m_profile.display_aspect_num / m_profile.display_aspect_den > 1.5) {
|
||||
std += QLatin1String("_wide");
|
||||
if ((double) profile->display_aspect_num() / profile->display_aspect_den() > 1.5) {
|
||||
dvstd += QLatin1String("_wide");
|
||||
}
|
||||
renderArgs.replace(QLatin1String("%dv_standard"), std);
|
||||
renderArgs.replace(QLatin1String("%dv_standard"), dvstd);
|
||||
}
|
||||
|
||||
// If there is an fps change, we need to use the producer consumer AND update the in/out points
|
||||
if (forcedfps > 0 && qAbs((int) 100 * forcedfps - ((int) 100 * m_profile.frame_rate_num / m_profile.frame_rate_den)) > 2) {
|
||||
if (forcedfps > 0 && qAbs((int) 100 * forcedfps - ((int) 100 * profile->frame_rate_num() / profile->frame_rate_den())) > 2) {
|
||||
resizeProfile = true;
|
||||
double ratio = m_profile.frame_rate_num / m_profile.frame_rate_den / forcedfps;
|
||||
double ratio = profile->frame_rate_num() / profile->frame_rate_den() / forcedfps;
|
||||
if (ratio > 0) {
|
||||
zoneIn /= ratio;
|
||||
zoneOut /= ratio;
|
||||
}
|
||||
}
|
||||
if (m_view.render_guide->isChecked()) {
|
||||
double fps = (double) m_profile.frame_rate_num / m_profile.frame_rate_den;
|
||||
double fps = profile->fps();
|
||||
double guideStart = m_view.guide_start->itemData(m_view.guide_start->currentIndex()).toDouble();
|
||||
double guideEnd = m_view.guide_end->itemData(m_view.guide_end->currentIndex()).toDouble();
|
||||
render_process_args << "in=" + QString::number((int) GenTime(guideStart).frames(fps)) << "out=" + QString::number((int) GenTime(guideEnd).frames(fps));
|
||||
@@ -1158,18 +1181,25 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
}
|
||||
|
||||
if (scriptExport) {
|
||||
render_process_args << QStringLiteral("$MELT");
|
||||
render_process_args << ScriptGetVar("MELT");
|
||||
} else {
|
||||
render_process_args << KdenliveSettings::rendererpath();
|
||||
}
|
||||
|
||||
render_process_args << m_profile.path << item->data(0, RenderRole).toString();
|
||||
render_process_args << profile->path() << item->data(0, RenderRole).toString();
|
||||
if (!scriptExport && m_view.play_after->isChecked()) {
|
||||
QMimeDatabase db;
|
||||
QMimeType mime = db.mimeTypeForFile(dest);
|
||||
KService::Ptr serv = KMimeTypeTrader::self()->preferredService(mime.name());
|
||||
KIO::DesktopExecParser parser(*serv, QList<QUrl>() << QUrl::fromLocalFile(QUrl::toPercentEncoding(dest)));
|
||||
render_process_args << parser.resultingArguments().join(QLatin1Char(' '));
|
||||
if (serv) {
|
||||
KIO::DesktopExecParser parser(*serv, QList<QUrl>() << QUrl::fromLocalFile(QUrl::toPercentEncoding(dest)));
|
||||
render_process_args << parser.resultingArguments().join(QLatin1Char(' '));
|
||||
} else {
|
||||
// no service found to play MIME type
|
||||
//TODO: inform user
|
||||
//errorMessage(PlaybackError, i18n("No service found to play %1", mime.name()));
|
||||
render_process_args << QStringLiteral("-");
|
||||
}
|
||||
} else {
|
||||
render_process_args << QStringLiteral("-");
|
||||
}
|
||||
@@ -1194,20 +1224,20 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
width = m_view.rescale_width->value();
|
||||
height = m_view.rescale_height->value();
|
||||
} else {
|
||||
width = m_profile.width;
|
||||
height = m_profile.height;
|
||||
width = profile->width();
|
||||
height = profile->height();
|
||||
}
|
||||
|
||||
// Adjust scanning
|
||||
if (m_view.scanning_list->currentIndex() == 1) {
|
||||
renderArgs.append(" progressive=1");
|
||||
renderArgs.append(QStringLiteral(" progressive=1"));
|
||||
} else if (m_view.scanning_list->currentIndex() == 2) {
|
||||
renderArgs.append(" progressive=0");
|
||||
renderArgs.append(QStringLiteral(" progressive=0"));
|
||||
}
|
||||
|
||||
// disable audio if requested
|
||||
if (!exportAudio) {
|
||||
renderArgs.append(" an=1 ");
|
||||
renderArgs.append(QStringLiteral(" an=1 "));
|
||||
}
|
||||
|
||||
// Set the thread counts
|
||||
@@ -1220,11 +1250,11 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
// in which case we need to use the producer_comsumer from MLT
|
||||
QString subsize;
|
||||
if (std.startsWith(QLatin1String("s="))) {
|
||||
subsize = std.section(' ', 0, 0).toLower();
|
||||
subsize = subsize.section('=', 1, 1);
|
||||
subsize = std.section(QLatin1Char(' '), 0, 0).toLower();
|
||||
subsize = subsize.section(QLatin1Char('='), 1, 1);
|
||||
} else if (std.contains(QStringLiteral(" s="))) {
|
||||
subsize = std.section(QStringLiteral(" s="), 1, 1);
|
||||
subsize = subsize.section(' ', 0, 0).toLower();
|
||||
subsize = subsize.section(QLatin1Char(' '), 0, 0).toLower();
|
||||
} else if (m_view.rescale->isChecked() && m_view.rescale->isEnabled()) {
|
||||
subsize = QStringLiteral(" s=%1x%2").arg(width).arg(height);
|
||||
// Add current size parameter
|
||||
@@ -1232,42 +1262,50 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
}
|
||||
// Check if we need to embed the playlist into the producer consumer
|
||||
// That is required if PAR != 1
|
||||
if (m_profile.sample_aspect_num != m_profile.sample_aspect_den && subsize.isEmpty()) {
|
||||
if (profile->sample_aspect_num() != profile->sample_aspect_den() && subsize.isEmpty()) {
|
||||
resizeProfile = true;
|
||||
}
|
||||
|
||||
QStringList paramsList = renderArgs.split(' ', QString::SkipEmptyParts);
|
||||
|
||||
QScriptEngine sEngine;
|
||||
sEngine.globalObject().setProperty(QStringLiteral("bitrate"), m_view.video->value());
|
||||
sEngine.globalObject().setProperty(QStringLiteral("quality"), m_view.video->value());
|
||||
sEngine.globalObject().setProperty(QStringLiteral("audiobitrate"), m_view.audio->value());
|
||||
sEngine.globalObject().setProperty(QStringLiteral("audioquality"), m_view.audio->value());
|
||||
sEngine.globalObject().setProperty(QStringLiteral("dar"), '@' + QString::number(m_profile.display_aspect_num) + '/' + QString::number(m_profile.display_aspect_den));
|
||||
sEngine.globalObject().setProperty(QStringLiteral("passes"), static_cast<int>(m_view.checkTwoPass->isChecked()) + 1);
|
||||
|
||||
for (int i = 0; i < paramsList.count(); ++i) {
|
||||
QString paramName = paramsList.at(i).section('=', 0, -2);
|
||||
QString paramValue = paramsList.at(i).section('=', -1);
|
||||
QString paramName = paramsList.at(i).section(QLatin1Char('='), 0, -2);
|
||||
QString paramValue = paramsList.at(i).section(QLatin1Char('='), -1);
|
||||
// If the profiles do not match we need to use the consumer tag
|
||||
if (paramName == QLatin1String("mlt_profile") && paramValue != m_profile.path) {
|
||||
if (paramName == QLatin1String("mlt_profile") && paramValue != profile->path()) {
|
||||
resizeProfile = true;
|
||||
}
|
||||
// evaluate expression
|
||||
if (paramValue.startsWith('%')) {
|
||||
paramValue = sEngine.evaluate(paramValue.remove(0, 1)).toString();
|
||||
paramsList[i] = paramName + '=' + paramValue;
|
||||
if (paramValue.startsWith(QLatin1Char('%'))) {
|
||||
if (paramValue.startsWith(QStringLiteral("%bitrate"))
|
||||
|| paramValue == QStringLiteral("%quality")) {
|
||||
if (paramValue.contains("+'k'"))
|
||||
paramValue = QString::number(m_view.video->value()) + 'k';
|
||||
else
|
||||
paramValue = QString::number(m_view.video->value());
|
||||
}
|
||||
if (paramValue.startsWith(QStringLiteral("%audiobitrate"))
|
||||
|| paramValue == QStringLiteral("%audioquality")) {
|
||||
if (paramValue.contains("+'k'"))
|
||||
paramValue = QString::number(m_view.audio->value()) + 'k';
|
||||
else
|
||||
paramValue = QString::number(m_view.audio->value());
|
||||
}
|
||||
if (paramValue == QStringLiteral("%dar"))
|
||||
paramValue = '@' + QString::number(profile->display_aspect_num()) + QLatin1Char('/') + QString::number(profile->display_aspect_den());
|
||||
if (paramValue == QStringLiteral("%passes"))
|
||||
paramValue = QString::number(static_cast<int>(m_view.checkTwoPass->isChecked()) + 1);
|
||||
paramsList[i] = paramName + QLatin1Char('=') + paramValue;
|
||||
}
|
||||
sEngine.globalObject().setProperty(paramName.toUtf8().constData(), paramValue);
|
||||
}
|
||||
|
||||
if (resizeProfile && !KdenliveSettings::gpu_accel()) {
|
||||
render_process_args << "consumer:" + (scriptExport ? "$SOURCE_" + QString::number(stemIdx) : QUrl::fromLocalFile(playlistPaths.at(stemIdx)).toEncoded());
|
||||
render_process_args << "consumer:" + (scriptExport ? ScriptGetVar("SOURCE_" + QString::number(stemIdx)) : QUrl::fromLocalFile(playlistPaths.at(stemIdx)).toEncoded());
|
||||
} else {
|
||||
render_process_args << (scriptExport ? "$SOURCE_" + QString::number(stemIdx) : QUrl::fromLocalFile(playlistPaths.at(stemIdx)).toEncoded());
|
||||
render_process_args << (scriptExport ? ScriptGetVar("SOURCE_" + QString::number(stemIdx)) : QUrl::fromLocalFile(playlistPaths.at(stemIdx)).toEncoded());
|
||||
}
|
||||
|
||||
render_process_args << (scriptExport ? "$TARGET_" + QString::number(stemIdx) : QUrl::fromLocalFile(dest).toEncoded());
|
||||
render_process_args << (scriptExport ? ScriptGetVar("TARGET_" + QString::number(stemIdx)) : QUrl::fromLocalFile(dest).toEncoded());
|
||||
if (KdenliveSettings::gpu_accel()) {
|
||||
render_process_args << QStringLiteral("glsl.=1");
|
||||
}
|
||||
@@ -1277,10 +1315,10 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
QTextStream outStream(&file);
|
||||
QString stemIdxStr(QString::number(stemIdx));
|
||||
|
||||
outStream << "SOURCE_" << stemIdxStr << "=" << '\"' + QUrl::fromLocalFile(playlistPaths.at(stemIdx)).toEncoded() + '\"' << '\n';
|
||||
outStream << "TARGET_" << stemIdxStr << "=" << '\"' + QUrl::fromLocalFile(dest).toEncoded() + '\"' << '\n';
|
||||
outStream << "PARAMETERS_" << stemIdxStr << "=" << '\"' + render_process_args.join(QLatin1Char(' ')) + '\"' << '\n';
|
||||
outStream << "$RENDERER $PARAMETERS_" << stemIdxStr << "\n\n";
|
||||
outStream << ScriptSetVar("SOURCE_" + stemIdxStr, QUrl::fromLocalFile(playlistPaths.at(stemIdx)).toEncoded()) << '\n';
|
||||
outStream << ScriptSetVar("TARGET_" + stemIdxStr, QUrl::fromLocalFile(dest).toEncoded()) << '\n';
|
||||
outStream << ScriptSetVar("PARAMETERS_" + stemIdxStr, render_process_args.join(QLatin1Char(' '))) << '\n';
|
||||
outStream << ScriptGetVar("RENDERER") + " " + ScriptGetVar("PARAMETERS_" + stemIdxStr) << "\n";
|
||||
|
||||
if (stemIdx == (stemCount - 1)) {
|
||||
if (file.error() != QFile::NoError) {
|
||||
@@ -1366,7 +1404,7 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut,
|
||||
//TODO: probably not valid anymore (no more MLT profiles in args)
|
||||
// rendering profile contains an MLT profile, so pass it to the running jog item, useful for dvd
|
||||
QString prof = renderArgs.section(QStringLiteral("mlt_profile="), 1, 1);
|
||||
prof = prof.section(' ', 0, 0);
|
||||
prof = prof.section(QLatin1Char(' '), 0, 0);
|
||||
qCDebug(KDENLIVE_LOG) << "// render profile: " << prof;
|
||||
renderItem->setMetadata(prof);
|
||||
}
|
||||
@@ -1440,7 +1478,7 @@ void RenderWidget::startRendering(RenderJobItem *item)
|
||||
}
|
||||
} else if (item->type() == ScriptRenderType) {
|
||||
// Script item
|
||||
if (QProcess::startDetached('"' + item->data(1, ParametersRole).toString() + '"') == false) {
|
||||
if (QProcess::startDetached(QLatin1Char('"') + item->data(1, ParametersRole).toString() + QLatin1Char('"')) == false) {
|
||||
item->setStatus(FAILEDJOB);
|
||||
}
|
||||
}
|
||||
@@ -1459,7 +1497,7 @@ int RenderWidget::waitingJobsCount() const
|
||||
return count;
|
||||
}
|
||||
|
||||
void RenderWidget::setProfile(const MltVideoProfile &profile)
|
||||
void RenderWidget::setProfile(const QString &profile)
|
||||
{
|
||||
m_view.scanning_list->setCurrentIndex(0);
|
||||
m_view.rescale_width->setValue(KdenliveSettings::defaultrescalewidth());
|
||||
@@ -1483,30 +1521,33 @@ void RenderWidget::refreshView()
|
||||
KColorScheme scheme(palette().currentColorGroup(), KColorScheme::Window);
|
||||
const QColor disabled = scheme.foreground(KColorScheme::InactiveText).color();
|
||||
const QColor disabledbg = scheme.background(KColorScheme::NegativeBackground).color();
|
||||
double project_framerate = (double) m_profile.frame_rate_num / m_profile.frame_rate_den;
|
||||
|
||||
//We borrow a reference to the profile's pointer to query it more easily
|
||||
std::unique_ptr<ProfileModel> &profile = ProfileRepository::get()->getProfile(m_profile);
|
||||
double project_framerate = (double) profile->frame_rate_num() / profile->frame_rate_den();
|
||||
for (int i = 0; i < m_view.formats->topLevelItemCount(); ++i) {
|
||||
QTreeWidgetItem *group = m_view.formats->topLevelItem(i);
|
||||
for (int j = 0; j < group->childCount(); ++j) {
|
||||
QTreeWidgetItem *item = group->child(j);
|
||||
QString std = item->data(0, StandardRole).toString();
|
||||
if (std.isEmpty()
|
||||
|| (std.contains(QStringLiteral("PAL"), Qt::CaseInsensitive) && m_profile.frame_rate_num == 25 && m_profile.frame_rate_den == 1)
|
||||
|| (std.contains(QStringLiteral("NTSC"), Qt::CaseInsensitive) && m_profile.frame_rate_num == 30000 && m_profile.frame_rate_den == 1001)
|
||||
|| (std.contains(QStringLiteral("PAL"), Qt::CaseInsensitive) && profile->frame_rate_num() == 25 && profile->frame_rate_den() == 1)
|
||||
|| (std.contains(QStringLiteral("NTSC"), Qt::CaseInsensitive) && profile->frame_rate_num() == 30000 && profile->frame_rate_den() == 1001)
|
||||
) {
|
||||
// Standard OK
|
||||
} else {
|
||||
item->setData(0, ErrorRole, i18n("Standard (%1) not compatible with project profile (%2)", std, (double) m_profile.frame_rate_num / m_profile.frame_rate_den));
|
||||
item->setData(0, ErrorRole, i18n("Standard (%1) not compatible with project profile (%2)", std, project_framerate));
|
||||
item->setIcon(0, brokenIcon);
|
||||
item->setForeground(0, disabled);
|
||||
continue;
|
||||
}
|
||||
std = item->data(0, ParamsRole).toString();
|
||||
QString params = item->data(0, ParamsRole).toString();
|
||||
// Make sure the selected profile uses the same frame rate as project profile
|
||||
if (std.contains(QStringLiteral("mlt_profile="))) {
|
||||
QString profile = std.section(QStringLiteral("mlt_profile="), 1, 1).section(' ', 0, 0);
|
||||
MltVideoProfile p = ProfilesDialog::getVideoProfile(profile);
|
||||
if (p.frame_rate_den > 0) {
|
||||
double profile_rate = (double) p.frame_rate_num / p.frame_rate_den;
|
||||
if (params.contains(QStringLiteral("mlt_profile="))) {
|
||||
QString profile_str = params.section(QStringLiteral("mlt_profile="), 1, 1).section(QLatin1Char(' '), 0, 0);
|
||||
std::unique_ptr<ProfileModel>& target_profile = ProfileRepository::get()->getProfile(profile_str);
|
||||
if (target_profile->frame_rate_den() > 0) {
|
||||
double profile_rate = (double) target_profile->frame_rate_num() / target_profile->frame_rate_den();
|
||||
if ((int)(1000.0 * profile_rate) != (int)(1000.0 * project_framerate)) {
|
||||
item->setData(0, ErrorRole, i18n("Frame rate (%1) not compatible with project profile (%2)", profile_rate, project_framerate));
|
||||
item->setIcon(0, brokenIcon);
|
||||
@@ -1519,13 +1560,13 @@ void RenderWidget::refreshView()
|
||||
// Make sure the selected profile uses an installed avformat codec / format
|
||||
if (!supportedFormats.isEmpty()) {
|
||||
QString format;
|
||||
if (std.startsWith(QLatin1String("f="))) {
|
||||
format = std.section(QStringLiteral("f="), 1, 1);
|
||||
} else if (std.contains(QStringLiteral(" f="))) {
|
||||
format = std.section(QStringLiteral(" f="), 1, 1);
|
||||
if (params.startsWith(QLatin1String("f="))) {
|
||||
format = params.section(QStringLiteral("f="), 1, 1);
|
||||
} else if (params.contains(QStringLiteral(" f="))) {
|
||||
format = params.section(QStringLiteral(" f="), 1, 1);
|
||||
}
|
||||
if (!format.isEmpty()) {
|
||||
format = format.section(' ', 0, 0).toLower();
|
||||
format = format.section(QLatin1Char(' '), 0, 0).toLower();
|
||||
if (!supportedFormats.contains(format)) {
|
||||
item->setData(0, ErrorRole, i18n("Unsupported video format: %1", format));
|
||||
item->setIcon(0, brokenIcon);
|
||||
@@ -1536,13 +1577,13 @@ void RenderWidget::refreshView()
|
||||
}
|
||||
if (!acodecsList.isEmpty()) {
|
||||
QString format;
|
||||
if (std.startsWith(QLatin1String("acodec="))) {
|
||||
format = std.section(QStringLiteral("acodec="), 1, 1);
|
||||
} else if (std.contains(QStringLiteral(" acodec="))) {
|
||||
format = std.section(QStringLiteral(" acodec="), 1, 1);
|
||||
if (params.startsWith(QLatin1String("acodec="))) {
|
||||
format = params.section(QStringLiteral("acodec="), 1, 1);
|
||||
} else if (params.contains(QStringLiteral(" acodec="))) {
|
||||
format = params.section(QStringLiteral(" acodec="), 1, 1);
|
||||
}
|
||||
if (!format.isEmpty()) {
|
||||
format = format.section(' ', 0, 0).toLower();
|
||||
format = format.section(QLatin1Char(' '), 0, 0).toLower();
|
||||
if (!acodecsList.contains(format)) {
|
||||
item->setData(0, ErrorRole, i18n("Unsupported audio codec: %1", format));
|
||||
item->setIcon(0, brokenIcon);
|
||||
@@ -1553,13 +1594,13 @@ void RenderWidget::refreshView()
|
||||
}
|
||||
if (!vcodecsList.isEmpty()) {
|
||||
QString format;
|
||||
if (std.startsWith(QLatin1String("vcodec="))) {
|
||||
format = std.section(QStringLiteral("vcodec="), 1, 1);
|
||||
} else if (std.contains(QStringLiteral(" vcodec="))) {
|
||||
format = std.section(QStringLiteral(" vcodec="), 1, 1);
|
||||
if (params.startsWith(QLatin1String("vcodec="))) {
|
||||
format = params.section(QStringLiteral("vcodec="), 1, 1);
|
||||
} else if (params.contains(QStringLiteral(" vcodec="))) {
|
||||
format = params.section(QStringLiteral(" vcodec="), 1, 1);
|
||||
}
|
||||
if (!format.isEmpty()) {
|
||||
format = format.section(' ', 0, 0).toLower();
|
||||
format = format.section(QLatin1Char(' '), 0, 0).toLower();
|
||||
if (!vcodecsList.contains(format)) {
|
||||
item->setData(0, ErrorRole, i18n("Unsupported video codec: %1", format));
|
||||
item->setIcon(0, brokenIcon);
|
||||
@@ -1568,7 +1609,7 @@ void RenderWidget::refreshView()
|
||||
}
|
||||
}
|
||||
}
|
||||
if (std.contains(QStringLiteral(" profile=")) || std.startsWith(QLatin1String("profile="))) {
|
||||
if (params.contains(QStringLiteral(" profile=")) || params.startsWith(QLatin1String("profile="))) {
|
||||
// changed in MLT commit d8a3a5c9190646aae72048f71a39ee7446a3bd45
|
||||
// (http://www.mltframework.org/gitweb/mlt.git?p=mltframework.org/mlt.git;a=commit;h=d8a3a5c9190646aae72048f71a39ee7446a3bd45)
|
||||
item->setData(0, ErrorRole, i18n("This render profile uses a 'profile' parameter.<br />Unless you know what you are doing you will probably have to change it to 'mlt_profile'."));
|
||||
@@ -1660,7 +1701,7 @@ void RenderWidget::refreshParams()
|
||||
// else path = path.left(pos) + extension;
|
||||
// m_view.out_file->setUrl(QUrl(path));
|
||||
// } else {
|
||||
// m_view.out_file->setUrl(QUrl(QDir::homePath() + "/untitled." + extension));
|
||||
// m_view.out_file->setUrl(QUrl(QDir::homePath() + QStringLiteral("/untitled.") + extension));
|
||||
// }
|
||||
m_view.out_file->setFilter("*." + extension);
|
||||
QString edit = item->data(0, EditableRole).toString();
|
||||
@@ -1681,7 +1722,7 @@ void RenderWidget::refreshParams()
|
||||
QStringList qs = item->data(0, BitratesRole).toStringList();
|
||||
if (qs.count() > 1) {
|
||||
quality = true;
|
||||
int qmax = qs.first().toInt();
|
||||
int qmax = qs.constFirst().toInt();
|
||||
int qmin = qs.last().toInt();
|
||||
if (qmax < qmin) {
|
||||
// always show best quality on right
|
||||
@@ -1707,7 +1748,7 @@ void RenderWidget::refreshParams()
|
||||
QStringList qs = item->data(0, AudioBitratesRole).toStringList();
|
||||
if (qs.count() > 1) {
|
||||
quality = true;
|
||||
int qmax = qs.first().toInt();
|
||||
int qmax = qs.constFirst().toInt();
|
||||
int qmin = qs.last().toInt();
|
||||
if (qmax < qmin) {
|
||||
m_view.audio->setRange(qmax, qmin);
|
||||
@@ -1762,7 +1803,7 @@ void RenderWidget::parseProfiles(const QString &selectedProfile)
|
||||
// Parse some MLT's profiles
|
||||
parseMltPresets();
|
||||
|
||||
QString exportFolder = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/export/";
|
||||
QString exportFolder = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/export/");
|
||||
QDir directory(exportFolder);
|
||||
QStringList filter;
|
||||
filter << QStringLiteral("*.xml");
|
||||
@@ -1773,8 +1814,8 @@ void RenderWidget::parseProfiles(const QString &selectedProfile)
|
||||
foreach (const QString &filename, fileList) {
|
||||
parseFile(directory.absoluteFilePath(filename), true);
|
||||
}
|
||||
if (QFile::exists(exportFolder + "customprofiles.xml")) {
|
||||
parseFile(exportFolder + "customprofiles.xml", true);
|
||||
if (QFile::exists(exportFolder + QStringLiteral("customprofiles.xml"))) {
|
||||
parseFile(exportFolder + QStringLiteral("customprofiles.xml"), true);
|
||||
}
|
||||
|
||||
focusFirstVisibleItem(selectedProfile);
|
||||
@@ -1800,8 +1841,8 @@ void RenderWidget::parseMltPresets()
|
||||
groupItem->setExpanded(true);
|
||||
}
|
||||
|
||||
QStringList profiles = root.entryList(QDir::Files, QDir::Name);
|
||||
foreach (const QString &prof, profiles) {
|
||||
const QStringList profiles = root.entryList(QDir::Files, QDir::Name);
|
||||
for (const QString &prof : profiles) {
|
||||
KConfig config(root.absoluteFilePath(prof), KConfig::SimpleConfig);
|
||||
KConfigGroup group = config.group(QByteArray());
|
||||
QString vcodec = group.readEntry("vcodec");
|
||||
@@ -1819,7 +1860,7 @@ void RenderWidget::parseMltPresets()
|
||||
} else if (!acodec.isEmpty()) {
|
||||
profileName.append(acodec);
|
||||
}
|
||||
profileName.append(")");
|
||||
profileName.append(QLatin1Char(')'));
|
||||
}
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(profileName));
|
||||
item->setData(0, ExtensionRole, extension);
|
||||
@@ -1911,20 +1952,20 @@ void RenderWidget::parseFile(const QString &exportFile, bool editable)
|
||||
QDomNodeList profilelist = doc.elementsByTagName(QStringLiteral("profile"));
|
||||
for (int i = 0; i < profilelist.count(); ++i) {
|
||||
QString category = i18nc("Category Name", "Custom");
|
||||
QString extension;
|
||||
QString ext;
|
||||
QDomNode parent = profilelist.at(i).parentNode();
|
||||
if (!parent.isNull()) {
|
||||
QDomElement parentNode = parent.toElement();
|
||||
if (parentNode.hasAttribute(QStringLiteral("name"))) {
|
||||
category = parentNode.attribute(QStringLiteral("name"));
|
||||
}
|
||||
extension = parentNode.attribute(QStringLiteral("extension"));
|
||||
ext = parentNode.attribute(QStringLiteral("extension"));
|
||||
}
|
||||
if (!profilelist.at(i).toElement().hasAttribute(QStringLiteral("category"))) {
|
||||
profilelist.at(i).toElement().setAttribute(QStringLiteral("category"), category);
|
||||
}
|
||||
if (!extension.isEmpty()) {
|
||||
profilelist.at(i).toElement().setAttribute(QStringLiteral("extension"), extension);
|
||||
if (!ext.isEmpty()) {
|
||||
profilelist.at(i).toElement().setAttribute(QStringLiteral("extension"), ext);
|
||||
}
|
||||
QDomNode n = profilelist.at(i).cloneNode();
|
||||
newprofiles.appendChild(newdoc.importNode(n, true));
|
||||
@@ -1983,46 +2024,46 @@ void RenderWidget::parseFile(const QString &exportFile, bool editable)
|
||||
|
||||
// Check if item with same name already exists and replace it,
|
||||
// allowing to override default profiles
|
||||
QTreeWidgetItem *item = nullptr;
|
||||
QTreeWidgetItem *childitem = nullptr;
|
||||
for (int j = 0; j < groupItem->childCount(); ++j) {
|
||||
if (groupItem->child(j)->text(0) == profileName) {
|
||||
item = groupItem->child(j);
|
||||
childitem = groupItem->child(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!item) {
|
||||
item = new QTreeWidgetItem(QStringList(profileName));
|
||||
if (!childitem) {
|
||||
childitem = new QTreeWidgetItem(QStringList(profileName));
|
||||
}
|
||||
item->setData(0, GroupRole, groupName);
|
||||
item->setData(0, ExtensionRole, extension);
|
||||
item->setData(0, RenderRole, "avformat");
|
||||
item->setData(0, StandardRole, standard);
|
||||
item->setData(0, ParamsRole, params);
|
||||
childitem->setData(0, GroupRole, groupName);
|
||||
childitem->setData(0, ExtensionRole, extension);
|
||||
childitem->setData(0, RenderRole, "avformat");
|
||||
childitem->setData(0, StandardRole, standard);
|
||||
childitem->setData(0, ParamsRole, params);
|
||||
if (params.contains(QLatin1String("%quality"))) {
|
||||
item->setData(0, BitratesRole, profile.attribute(QStringLiteral("qualities")).split(',', QString::SkipEmptyParts));
|
||||
childitem->setData(0, BitratesRole, profile.attribute(QStringLiteral("qualities")).split(QLatin1Char(','), QString::SkipEmptyParts));
|
||||
} else if (params.contains(QLatin1String("%bitrate"))) {
|
||||
item->setData(0, BitratesRole, profile.attribute(QStringLiteral("bitrates")).split(',', QString::SkipEmptyParts));
|
||||
childitem->setData(0, BitratesRole, profile.attribute(QStringLiteral("bitrates")).split(QLatin1Char(','), QString::SkipEmptyParts));
|
||||
}
|
||||
if (params.contains(QLatin1String("%audioquality"))) {
|
||||
item->setData(0, AudioBitratesRole, profile.attribute(QStringLiteral("audioqualities")).split(',', QString::SkipEmptyParts));
|
||||
childitem->setData(0, AudioBitratesRole, profile.attribute(QStringLiteral("audioqualities")).split(QLatin1Char(','), QString::SkipEmptyParts));
|
||||
} else if (params.contains(QLatin1String("%audiobitrate"))) {
|
||||
item->setData(0, AudioBitratesRole, profile.attribute(QStringLiteral("audiobitrates")).split(',', QString::SkipEmptyParts));
|
||||
childitem->setData(0, AudioBitratesRole, profile.attribute(QStringLiteral("audiobitrates")).split(QLatin1Char(','), QString::SkipEmptyParts));
|
||||
}
|
||||
if (profile.hasAttribute(QStringLiteral("speeds"))) {
|
||||
item->setData(0, SpeedsRole, profile.attribute(QStringLiteral("speeds")).split(';', QString::SkipEmptyParts));
|
||||
childitem->setData(0, SpeedsRole, profile.attribute(QStringLiteral("speeds")).split(QLatin1Char(';'), QString::SkipEmptyParts));
|
||||
}
|
||||
if (profile.hasAttribute(QStringLiteral("url"))) {
|
||||
item->setData(0, ExtraRole, profile.attribute(QStringLiteral("url")));
|
||||
childitem->setData(0, ExtraRole, profile.attribute(QStringLiteral("url")));
|
||||
}
|
||||
if (editable) {
|
||||
item->setData(0, EditableRole, exportFile);
|
||||
childitem->setData(0, EditableRole, exportFile);
|
||||
if (exportFile.endsWith(QLatin1String("customprofiles.xml"))) {
|
||||
item->setIcon(0, KoIconUtils::themedIcon(QStringLiteral("favorite")));
|
||||
childitem->setIcon(0, KoIconUtils::themedIcon(QStringLiteral("favorite")));
|
||||
} else {
|
||||
item->setIcon(0, QIcon::fromTheme(QStringLiteral("applications-internet")));
|
||||
childitem->setIcon(0, QIcon::fromTheme(QStringLiteral("applications-internet")));
|
||||
}
|
||||
}
|
||||
groupItem->addChild(item);
|
||||
groupItem->addChild(childitem);
|
||||
node = doc.elementsByTagName(QStringLiteral("profile")).at(count);
|
||||
count++;
|
||||
}
|
||||
@@ -2085,17 +2126,17 @@ void RenderWidget::parseFile(const QString &exportFile, bool editable)
|
||||
item->setData(0, StandardRole, standard);
|
||||
item->setData(0, ParamsRole, params);
|
||||
if (params.contains(QLatin1String("%quality"))) {
|
||||
item->setData(0, BitratesRole, profileElement.attribute(QStringLiteral("qualities")).split(',', QString::SkipEmptyParts));
|
||||
item->setData(0, BitratesRole, profileElement.attribute(QStringLiteral("qualities")).split(QLatin1Char(','), QString::SkipEmptyParts));
|
||||
} else if (params.contains(QLatin1String("%bitrate"))) {
|
||||
item->setData(0, BitratesRole, profileElement.attribute(QStringLiteral("bitrates")).split(',', QString::SkipEmptyParts));
|
||||
item->setData(0, BitratesRole, profileElement.attribute(QStringLiteral("bitrates")).split(QLatin1Char(','), QString::SkipEmptyParts));
|
||||
}
|
||||
if (params.contains(QLatin1String("%audioquality"))) {
|
||||
item->setData(0, AudioBitratesRole, profileElement.attribute(QStringLiteral("audioqualities")).split(',', QString::SkipEmptyParts));
|
||||
item->setData(0, AudioBitratesRole, profileElement.attribute(QStringLiteral("audioqualities")).split(QLatin1Char(','), QString::SkipEmptyParts));
|
||||
} else if (params.contains(QLatin1String("%audiobitrate"))) {
|
||||
item->setData(0, AudioBitratesRole, profileElement.attribute(QStringLiteral("audiobitrates")).split(',', QString::SkipEmptyParts));
|
||||
item->setData(0, AudioBitratesRole, profileElement.attribute(QStringLiteral("audiobitrates")).split(QLatin1Char(','), QString::SkipEmptyParts));
|
||||
}
|
||||
if (profileElement.hasAttribute(QStringLiteral("speeds"))) {
|
||||
item->setData(0, SpeedsRole, profileElement.attribute(QStringLiteral("speeds")).split(';', QString::SkipEmptyParts));
|
||||
item->setData(0, SpeedsRole, profileElement.attribute(QStringLiteral("speeds")).split(QLatin1Char(';'), QString::SkipEmptyParts));
|
||||
}
|
||||
if (profileElement.hasAttribute(QStringLiteral("url"))) {
|
||||
item->setData(0, ExtraRole, profileElement.attribute(QStringLiteral("url")));
|
||||
@@ -2128,13 +2169,12 @@ void RenderWidget::setRenderJob(const QString &dest, int progress)
|
||||
slotCheckJob();
|
||||
} else {
|
||||
QDateTime startTime = item->data(1, TimeRole).toDateTime();
|
||||
int days = startTime.daysTo(QDateTime::currentDateTime());
|
||||
double elapsedTime = days * 86400 + startTime.addDays(days).secsTo(QDateTime::currentDateTime());
|
||||
quint32 remaining = elapsedTime * (100.0 - progress) / progress;
|
||||
int remainingSecs = remaining % 86400;
|
||||
days = remaining / 86400;
|
||||
QTime when = QTime(0, 0, 0, 0);
|
||||
when = when.addSecs(remainingSecs);
|
||||
qint64 elapsedTime = startTime.secsTo(QDateTime::currentDateTime());
|
||||
qint64 remaining = elapsedTime * (100 - progress) / progress;
|
||||
int days = static_cast<int>(remaining / 86400);
|
||||
int remainingSecs = static_cast<int>(remaining % 86400);
|
||||
QTime when = QTime ( 0, 0, 0, 0 ) ;
|
||||
when = when.addSecs (remainingSecs) ;
|
||||
QString est = (days > 0) ? i18np("%1 day ", "%1 days ", days) : QString();
|
||||
est.append(when.toString(QStringLiteral("hh:mm:ss")));
|
||||
QString t = i18n("Remaining time %1", est);
|
||||
@@ -2158,17 +2198,22 @@ void RenderWidget::setRenderStatus(const QString &dest, int status, const QStrin
|
||||
// Job finished successfully
|
||||
item->setStatus(FINISHEDJOB);
|
||||
QDateTime startTime = item->data(1, TimeRole).toDateTime();
|
||||
int days = startTime.daysTo(QDateTime::currentDateTime());
|
||||
int elapsedTime = startTime.addDays(days).secsTo(QDateTime::currentDateTime());
|
||||
QTime when = QTime(0, 0, 0, 0);
|
||||
when = when.addSecs(elapsedTime);
|
||||
qint64 elapsedTime = startTime.secsTo(QDateTime::currentDateTime());
|
||||
int days = static_cast<int>(elapsedTime / 86400);
|
||||
int secs = static_cast<int>(elapsedTime % 86400);
|
||||
QTime when = QTime ( 0, 0, 0, 0 ) ;
|
||||
when = when.addSecs (secs) ;
|
||||
QString est = (days > 0) ? i18np("%1 day ", "%1 days ", days) : QString();
|
||||
est.append(when.toString(QStringLiteral("hh:mm:ss")));
|
||||
QString t = i18n("Rendering finished in %1", est);
|
||||
item->setData(1, Qt::UserRole, t);
|
||||
QString notif = i18n("Rendering of %1 finished in %2", item->text(1), est);
|
||||
//WARNING: notification below does not seem to work
|
||||
KNotification::event(QStringLiteral("RenderFinished"), notif, QPixmap(), this);
|
||||
KNotification *notify = new KNotification(QStringLiteral("RenderFinished"));
|
||||
notify->setText(notif);
|
||||
#if KNOTIFICATIONS_VERSION >= QT_VERSION_CHECK(5, 29, 0)
|
||||
notify->setUrls({QUrl::fromLocalFile(dest)});
|
||||
#endif
|
||||
notify->sendEvent();
|
||||
QString itemGroup = item->data(0, Qt::UserRole).toString();
|
||||
if (itemGroup == QLatin1String("dvd")) {
|
||||
emit openDvdWizard(item->text(1));
|
||||
@@ -2260,13 +2305,12 @@ void RenderWidget::slotCLeanUpJobs()
|
||||
void RenderWidget::parseScriptFiles()
|
||||
{
|
||||
QStringList scriptsFilter;
|
||||
scriptsFilter << QStringLiteral("*.sh");
|
||||
scriptsFilter << QLatin1Char('*') + ScriptFormat;
|
||||
m_view.scripts_list->clear();
|
||||
|
||||
QTreeWidgetItem *item;
|
||||
// List the project scripts
|
||||
QDir directory(m_projectFolder);
|
||||
directory.cd(QStringLiteral("scripts"));
|
||||
QDir directory(m_projectFolder + QStringLiteral("scripts/"));
|
||||
QStringList scriptFiles = directory.entryList(scriptsFilter, QDir::Files);
|
||||
for (int i = 0; i < scriptFiles.size(); ++i) {
|
||||
QUrl scriptpath = QUrl::fromLocalFile(directory.absoluteFilePath(scriptFiles.at(i)));
|
||||
@@ -2278,15 +2322,15 @@ void RenderWidget::parseScriptFiles()
|
||||
QTextStream stream(&file);
|
||||
while (!stream.atEnd()) {
|
||||
QString line = stream.readLine();
|
||||
if (line.startsWith(QLatin1String("TARGET_0="))) {
|
||||
target = line.section(QStringLiteral("TARGET_0=\""), 1);
|
||||
target = target.section('"', 0, 0);
|
||||
} else if (line.startsWith(QLatin1String("RENDERER="))) {
|
||||
renderer = line.section(QStringLiteral("RENDERER=\""), 1);
|
||||
renderer = renderer.section('"', 0, 0);
|
||||
} else if (line.startsWith(QLatin1String("MELT="))) {
|
||||
melt = line.section(QStringLiteral("MELT=\""), 1);
|
||||
melt = melt.section('"', 0, 0);
|
||||
if (line.contains(QLatin1String("TARGET_0="))) {
|
||||
target = line.section(QStringLiteral("TARGET_0="), 1);
|
||||
target = target.section(QLatin1Char('"'), 0, 0, QString::SectionSkipEmpty);
|
||||
} else if (line.contains(QLatin1String("RENDERER="))) {
|
||||
renderer = line.section(QStringLiteral("RENDERER="), 1);
|
||||
renderer = renderer.section(QLatin1Char('"'), 0, 0, QString::SectionSkipEmpty);
|
||||
} else if (line.contains(QLatin1String("MELT="))) {
|
||||
melt = line.section(QStringLiteral("MELT="), 1);
|
||||
melt = melt.section(QLatin1Char('"'), 0, 0, QString::SectionSkipEmpty);
|
||||
}
|
||||
}
|
||||
file.close();
|
||||
@@ -2374,7 +2418,7 @@ void RenderWidget::slotDeleteScript()
|
||||
if (item) {
|
||||
QString path = item->data(1, Qt::UserRole + 1).toString();
|
||||
bool success = true;
|
||||
success &= QFile::remove(path + ".mlt");
|
||||
success &= QFile::remove(path + QStringLiteral(".mlt"));
|
||||
success &= QFile::remove(path);
|
||||
if (!success) {
|
||||
qCWarning(KDENLIVE_LOG) << "// Error removing script or playlist: " << path << ", " << path << ".mlt";
|
||||
@@ -2483,14 +2527,16 @@ bool RenderWidget::startWaitingRenderJobs()
|
||||
}
|
||||
|
||||
QTextStream outStream(&file);
|
||||
#ifndef Q_OS_WIN
|
||||
outStream << "#! /bin/sh" << '\n' << '\n';
|
||||
#endif
|
||||
RenderJobItem *item = static_cast<RenderJobItem *>(m_view.running_jobs->topLevelItem(0));
|
||||
while (item) {
|
||||
if (item->status() == WAITINGJOB) {
|
||||
if (item->type() == DirectRenderType) {
|
||||
// Add render process for item
|
||||
const QString params = item->data(1, ParametersRole).toStringList().join(QLatin1Char(' '));
|
||||
outStream << m_renderer << ' ' << params << '\n';
|
||||
outStream << '\"' << m_renderer << "\" " << params << '\n';
|
||||
} else if (item->type() == ScriptRenderType) {
|
||||
// Script item
|
||||
outStream << item->data(1, ParametersRole).toString() << '\n';
|
||||
@@ -2499,7 +2545,11 @@ bool RenderWidget::startWaitingRenderJobs()
|
||||
item = static_cast<RenderJobItem *>(m_view.running_jobs->itemBelow(item));
|
||||
}
|
||||
// erase itself when rendering is finished
|
||||
outStream << "rm " << autoscriptFile << '\n' << '\n';
|
||||
#ifndef Q_OS_WIN
|
||||
outStream << "rm \"" << autoscriptFile << "\"\n";
|
||||
#else
|
||||
outStream << "del \"" << autoscriptFile << "\"\n";
|
||||
#endif
|
||||
if (file.error() != QFile::NoError) {
|
||||
KMessageBox::error(nullptr, i18n("Cannot write to file %1", autoscriptFile));
|
||||
file.close();
|
||||
@@ -2515,7 +2565,7 @@ bool RenderWidget::startWaitingRenderJobs()
|
||||
QString RenderWidget::getFreeScriptName(const QUrl &projectName, const QString &prefix)
|
||||
{
|
||||
int ix = 0;
|
||||
QString scriptsFolder = m_projectFolder + "scripts/";
|
||||
QString scriptsFolder = m_projectFolder + QStringLiteral("scripts/");
|
||||
QDir dir(m_projectFolder);
|
||||
dir.mkdir(QStringLiteral("scripts"));
|
||||
QString path;
|
||||
@@ -2523,11 +2573,11 @@ QString RenderWidget::getFreeScriptName(const QUrl &projectName, const QString &
|
||||
if (projectName.isEmpty()) {
|
||||
fileName = i18n("script");
|
||||
} else {
|
||||
fileName = projectName.fileName().section('.', 0, -2) + '_';
|
||||
fileName = projectName.fileName().section(QLatin1Char('.'), 0, -2) + QLatin1Char('_');
|
||||
}
|
||||
while (path.isEmpty() || QFile::exists(path)) {
|
||||
++ix;
|
||||
path = scriptsFolder + prefix + fileName + QString::number(ix).rightJustified(3, '0', false) + ".sh";
|
||||
path = scriptsFolder + prefix + fileName + QString::number(ix).rightJustified(3, '0', false) + ScriptFormat;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
@@ -2582,7 +2632,8 @@ void RenderWidget::slotUpdateRescaleWidth(int val)
|
||||
return;
|
||||
}
|
||||
m_view.rescale_height->blockSignals(true);
|
||||
m_view.rescale_height->setValue(val * m_profile.height / m_profile.width);
|
||||
std::unique_ptr<ProfileModel>& profile = ProfileRepository::get()->getProfile(m_profile);
|
||||
m_view.rescale_height->setValue(val * profile->height() / profile->width());
|
||||
KdenliveSettings::setDefaultrescaleheight(m_view.rescale_height->value());
|
||||
m_view.rescale_height->blockSignals(false);
|
||||
}
|
||||
@@ -2594,7 +2645,8 @@ void RenderWidget::slotUpdateRescaleHeight(int val)
|
||||
return;
|
||||
}
|
||||
m_view.rescale_width->blockSignals(true);
|
||||
m_view.rescale_width->setValue(val * m_profile.width / m_profile.height);
|
||||
std::unique_ptr<ProfileModel>& profile = ProfileRepository::get()->getProfile(m_profile);
|
||||
m_view.rescale_width->setValue(val * profile->width() / profile->height());
|
||||
KdenliveSettings::setDefaultrescaleheight(m_view.rescale_width->value());
|
||||
m_view.rescale_width->blockSignals(false);
|
||||
}
|
||||
|
||||
@@ -111,11 +111,11 @@ class RenderWidget : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit RenderWidget(const QString &projectfolder, bool enableProxy, const MltVideoProfile &profile, QWidget *parent = Q_NULLPTR);
|
||||
explicit RenderWidget(const QString &projectfolder, bool enableProxy, const QString &profile, QWidget *parent = nullptr);
|
||||
virtual ~RenderWidget();
|
||||
void setGuides(const QMap<double, QString> &guidesData, double duration);
|
||||
void focusFirstVisibleItem(const QString &profile = QString());
|
||||
void setProfile(const MltVideoProfile &profile);
|
||||
void setProfile(const QString &profile);
|
||||
void setRenderJob(const QString &dest, int progress = 0);
|
||||
void setRenderStatus(const QString &dest, int status, const QString &error);
|
||||
void setDocumentPath(const QString &path);
|
||||
@@ -137,7 +137,8 @@ public:
|
||||
enum RenderError {
|
||||
CompositeError = 0,
|
||||
ProfileError = 1,
|
||||
ProxyWarning = 2
|
||||
ProxyWarning = 2,
|
||||
PlaybackError = 3
|
||||
};
|
||||
|
||||
/** @brief Display warning message in render widget. */
|
||||
@@ -201,7 +202,7 @@ private slots:
|
||||
private:
|
||||
Ui::RenderWidget_UI m_view;
|
||||
QString m_projectFolder;
|
||||
MltVideoProfile m_profile;
|
||||
QString m_profile;
|
||||
RenderViewDelegate *m_scriptsDelegate;
|
||||
RenderViewDelegate *m_jobsDelegate;
|
||||
bool m_blockProcessing;
|
||||
|
||||
@@ -35,7 +35,7 @@ TitleTemplateDialog::TitleTemplateDialog(const QString &folder, QWidget *parent)
|
||||
m_view.setupUi(this);
|
||||
// Get the list of existing templates
|
||||
const QStringList filter = { QStringLiteral("*.kdenlivetitle") };
|
||||
const QString path = folder + "/titles/";
|
||||
const QString path = folder + QStringLiteral("/titles/");
|
||||
|
||||
// Project templates
|
||||
QDir dir(path);
|
||||
@@ -48,16 +48,20 @@ TitleTemplateDialog::TitleTemplateDialog(const QString &folder, QWidget *parent)
|
||||
const QStringList titleTemplates = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, QStringLiteral("titles/"), QStandardPaths::LocateDirectory);
|
||||
|
||||
for (const QString &folderpath : titleTemplates) {
|
||||
QDir folder(folderpath);
|
||||
const QStringList filesnames = folder.entryList(filter, QDir::Files);
|
||||
QDir sysdir(folderpath);
|
||||
const QStringList filesnames = sysdir.entryList(filter, QDir::Files);
|
||||
for (const QString &fname : filesnames) {
|
||||
m_view.template_list->comboBox()->addItem(fname, folder.absoluteFilePath(fname));
|
||||
m_view.template_list->comboBox()->addItem(fname, sysdir.absoluteFilePath(fname));
|
||||
}
|
||||
}
|
||||
|
||||
if (!templateFiles.isEmpty()) {
|
||||
if (m_view.template_list->comboBox()->count() > 0) {
|
||||
m_view.buttonBox->button(QDialogButtonBox::Ok)->setFocus();
|
||||
}
|
||||
int current = m_view.template_list->comboBox()->findText(KdenliveSettings::selected_template());
|
||||
if (current > -1) {
|
||||
m_view.template_list->comboBox()->setCurrentIndex(current);
|
||||
}
|
||||
const QStringList mimeTypeFilters = { QStringLiteral("application/x-kdenlivetitle") };
|
||||
m_view.template_list->setFilter(mimeTypeFilters.join(' '));
|
||||
connect(m_view.template_list->comboBox(), SIGNAL(currentIndexChanged(int)), this, SLOT(updatePreview()));
|
||||
@@ -86,4 +90,5 @@ void TitleTemplateDialog::updatePreview()
|
||||
}
|
||||
QPixmap pix = KThumb::getImage(QUrl::fromLocalFile(textTemplate), m_view.preview->width());
|
||||
m_view.preview->setPixmap(pix);
|
||||
KdenliveSettings::setSelected_template(m_view.template_list->comboBox()->currentText());
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ class TitleTemplateDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TitleTemplateDialog(const QString &folder, QWidget *parent = Q_NULLPTR);
|
||||
explicit TitleTemplateDialog(const QString &folder, QWidget *parent = nullptr);
|
||||
QString selectedTemplate() const;
|
||||
QString selectedText() const;
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ Wizard::Wizard(bool autoClose, QWidget *parent) :
|
||||
}
|
||||
if (!m_errors.isEmpty()) {
|
||||
KMessageWidget *errorLabel = new KMessageWidget(this);
|
||||
errorLabel->setText("<ul>" + m_errors + "</ul>");
|
||||
errorLabel->setText(QStringLiteral("<ul>") + m_errors + QStringLiteral("</ul>"));
|
||||
errorLabel->setMessageType(KMessageWidget::Error);
|
||||
errorLabel->setWordWrap(true);
|
||||
errorLabel->setCloseButtonVisible(false);
|
||||
@@ -141,7 +141,7 @@ Wizard::Wizard(bool autoClose, QWidget *parent) :
|
||||
}
|
||||
if (!m_warnings.isEmpty()) {
|
||||
KMessageWidget *errorLabel = new KMessageWidget(this);
|
||||
errorLabel->setText("<ul>" + m_warnings + "</ul>");
|
||||
errorLabel->setText(QStringLiteral("<ul>") + m_warnings + QStringLiteral("</ul>"));
|
||||
errorLabel->setMessageType(KMessageWidget::Warning);
|
||||
errorLabel->setWordWrap(true);
|
||||
errorLabel->setCloseButtonVisible(false);
|
||||
@@ -150,7 +150,7 @@ Wizard::Wizard(bool autoClose, QWidget *parent) :
|
||||
}
|
||||
if (!m_infos.isEmpty()) {
|
||||
KMessageWidget *errorLabel = new KMessageWidget(this);
|
||||
errorLabel->setText("<ul>" + m_infos + "</ul>");
|
||||
errorLabel->setText(QStringLiteral("<ul>") + m_infos + QStringLiteral("</ul>"));
|
||||
errorLabel->setMessageType(KMessageWidget::Information);
|
||||
errorLabel->setWordWrap(true);
|
||||
errorLabel->setCloseButtonVisible(false);
|
||||
@@ -275,7 +275,7 @@ void Wizard::slotUpdateCaptureParameters()
|
||||
m_capture.v4l_formats->blockSignals(true);
|
||||
m_capture.v4l_formats->clear();
|
||||
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/profiles/");
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/profiles/"));
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(QStringLiteral("."));
|
||||
}
|
||||
@@ -289,16 +289,16 @@ void Wizard::slotUpdateCaptureParameters()
|
||||
QString pixelFormat;
|
||||
QStringList itemRates;
|
||||
for (int i = 0; i < pixelformats.count(); ++i) {
|
||||
QString format = pixelformats.at(i).section(':', 0, 0);
|
||||
QString format = pixelformats.at(i).section(QLatin1Char(':'), 0, 0);
|
||||
QStringList sizes = pixelformats.at(i).split(':', QString::SkipEmptyParts);
|
||||
pixelFormat = sizes.takeFirst();
|
||||
for (int j = 0; j < sizes.count(); ++j) {
|
||||
itemSize = sizes.at(j).section('=', 0, 0);
|
||||
itemRates = sizes.at(j).section('=', 1, 1).split(',', QString::SkipEmptyParts);
|
||||
itemSize = sizes.at(j).section(QLatin1Char('='), 0, 0);
|
||||
itemRates = sizes.at(j).section(QLatin1Char('='), 1, 1).split(QLatin1Char(','), QString::SkipEmptyParts);
|
||||
for (int k = 0; k < itemRates.count(); ++k) {
|
||||
QString formatDescription = '[' + format + "] " + itemSize + " (" + itemRates.at(k) + ')';
|
||||
QString formatDescription = QLatin1Char('[') + format + QStringLiteral("] ") + itemSize + QStringLiteral(" (") + itemRates.at(k) + QLatin1Char(')');
|
||||
if (m_capture.v4l_formats->findText(formatDescription) == -1) {
|
||||
m_capture.v4l_formats->addItem(formatDescription, QStringList() << format << itemSize.section('x', 0, 0) << itemSize.section('x', 1, 1) << itemRates.at(k).section('/', 0, 0) << itemRates.at(k).section('/', 1, 1));
|
||||
m_capture.v4l_formats->addItem(formatDescription, QStringList() << format << itemSize.section('x', 0, 0) << itemSize.section('x', 1, 1) << itemRates.at(k).section(QLatin1Char('/'), 0, 0) << itemRates.at(k).section(QLatin1Char('/'), 1, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -366,10 +366,11 @@ void Wizard::checkMltComponents()
|
||||
m_warnings.append(i18n("<li>Missing package: <b>Frei0r</b> effects (frei0r-plugins)<br/>provides many effects and transitions. Install recommended</li>"));
|
||||
}
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
// Check that we have the breeze icon theme installed
|
||||
QStringList iconPaths = QIcon::themeSearchPaths();
|
||||
const QStringList iconPaths = QIcon::themeSearchPaths();
|
||||
bool hasBreeze = false;
|
||||
foreach (const QString &path, iconPaths) {
|
||||
for (const QString &path : iconPaths) {
|
||||
QDir dir(path);
|
||||
if (dir.exists(QStringLiteral("breeze"))) {
|
||||
hasBreeze = true;
|
||||
@@ -380,6 +381,7 @@ void Wizard::checkMltComponents()
|
||||
// Breeze icons not found
|
||||
m_warnings.append(i18n("<li>Missing package: <b>Breeze</b> icons (breeze-icon-theme)<br/>provides many icons used in Kdenlive. Install recommended</li>"));
|
||||
}
|
||||
#endif
|
||||
|
||||
Mlt::Properties *consumers = repository->consumers();
|
||||
QStringList consumersItemList;
|
||||
@@ -389,7 +391,18 @@ void Wizard::checkMltComponents()
|
||||
}
|
||||
delete consumers;
|
||||
|
||||
if (!consumersItemList.contains(QStringLiteral("sdl")) && !consumersItemList.contains(QStringLiteral("rtaudio"))) {
|
||||
if (consumersItemList.contains(QStringLiteral("sdl2"))) {
|
||||
// MLT >= 6.6.0 and SDL2 module
|
||||
KdenliveSettings::setSdlAudioBackend(QStringLiteral("sdl2_audio"));
|
||||
KdenliveSettings::setAudiobackend(QStringLiteral("sdl2_audio"));
|
||||
} else if (consumersItemList.contains(QStringLiteral("sdl"))) {
|
||||
// MLT < 6.6.0
|
||||
KdenliveSettings::setSdlAudioBackend(QStringLiteral("sdl_audio"));
|
||||
KdenliveSettings::setAudiobackend(QStringLiteral("sdl_audio"));
|
||||
} else if (consumersItemList.contains(QStringLiteral("rtaudio"))) {
|
||||
KdenliveSettings::setSdlAudioBackend(QStringLiteral("sdl2_audio"));
|
||||
KdenliveSettings::setAudiobackend(QStringLiteral("rtaudio"));
|
||||
} else {
|
||||
// SDL module
|
||||
m_errors.append(i18n("<li>Missing MLT module: <b>sdl</b> or <b>rtaudio</b><br/>required for audio output</li>"));
|
||||
m_systemCheckIsOk = false;
|
||||
@@ -461,11 +474,11 @@ void Wizard::checkMissingCodecs()
|
||||
}
|
||||
QStringList profilesList;
|
||||
profilesList << QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("export/profiles.xml"));
|
||||
QDir directory = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/export/");
|
||||
QDir directory = QDir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/export/"));
|
||||
QStringList filter;
|
||||
filter << QStringLiteral("*.xml");
|
||||
QStringList fileList = directory.entryList(filter, QDir::Files);
|
||||
foreach (const QString &filename, fileList) {
|
||||
const QStringList fileList = directory.entryList(filter, QDir::Files);
|
||||
for (const QString &filename : fileList) {
|
||||
profilesList << directory.absoluteFilePath(filename);
|
||||
}
|
||||
|
||||
@@ -490,7 +503,7 @@ void Wizard::checkMissingCodecs()
|
||||
format = std.section(QStringLiteral(" acodec="), 1, 1);
|
||||
}
|
||||
if (!format.isEmpty()) {
|
||||
requiredACodecs << format.section(' ', 0, 0).toLower();
|
||||
requiredACodecs << format.section(QLatin1Char(' '), 0, 0).toLower();
|
||||
}
|
||||
format.clear();
|
||||
if (std.startsWith(QLatin1String("vcodec="))) {
|
||||
@@ -499,7 +512,7 @@ void Wizard::checkMissingCodecs()
|
||||
format = std.section(QStringLiteral(" vcodec="), 1, 1);
|
||||
}
|
||||
if (!format.isEmpty()) {
|
||||
requiredVCodecs << format.section(' ', 0, 0).toLower();
|
||||
requiredVCodecs << format.section(QLatin1Char(' '), 0, 0).toLower();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -658,7 +671,7 @@ void Wizard::installExtraMimes(const QString &baseName, const QStringList &globs
|
||||
return;
|
||||
}
|
||||
if (!mime.isValid() || mime.isDefault()) {
|
||||
qCDebug(KDENLIVE_LOG) << "mimeType " << baseName << " not found";
|
||||
qCDebug(KDENLIVE_LOG) << "MIME type " << baseName << " not found";
|
||||
} else {
|
||||
QStringList extensions = mime.globPatterns();
|
||||
QString comment = mime.comment();
|
||||
@@ -672,7 +685,7 @@ void Wizard::installExtraMimes(const QString &baseName, const QStringList &globs
|
||||
if (!mimeDir.exists()) {
|
||||
mimeDir.mkpath(QStringLiteral("."));
|
||||
}
|
||||
QString packageFileName = mimeDir.absoluteFilePath(mimefile + ".xml");
|
||||
QString packageFileName = mimeDir.absoluteFilePath(mimefile + QStringLiteral(".xml"));
|
||||
//qCDebug(KDENLIVE_LOG) << "INSTALLING NEW MIME TO: " << packageFileName;
|
||||
QFile packageFile(packageFileName);
|
||||
if (!packageFile.open(QIODevice::WriteOnly)) {
|
||||
@@ -756,7 +769,9 @@ void Wizard::slotCheckStandard()
|
||||
QListWidgetItem *item = m_standard.profiles_list->item(i);
|
||||
|
||||
QMap< QString, QString > values = ProfilesDialog::getSettingsFromFile(item->data(Qt::UserRole).toString());
|
||||
const QString infoString = ("<strong>" + i18n("Frame size:") + " </strong>%1x%2<br /><strong>" + i18n("Frame rate:") + " </strong>%3/%4<br /><strong>" + i18n("Pixel aspect ratio:") + "</strong>%5/%6<br /><strong>" + i18n("Display aspect ratio:") + " </strong>%7/%8").arg(values.value(QStringLiteral("width")), values.value(QStringLiteral("height")), values.value(QStringLiteral("frame_rate_num")), values.value(QStringLiteral("frame_rate_den")), values.value(QStringLiteral("sample_aspect_num")), values.value(QStringLiteral("sample_aspect_den")), values.value(QStringLiteral("display_aspect_num")), values.value(QStringLiteral("display_aspect_den")));
|
||||
const QString infoString = ("<strong>" + i18n("Frame size:") + QStringLiteral(" </strong>%1x%2<br /><strong>") + i18n("Frame rate:") + QStringLiteral(" </strong>%3/%4<br /><strong>")
|
||||
+ i18n("Pixel aspect ratio:") + QStringLiteral("</strong>%5/%6<br /><strong>") + i18n("Display aspect ratio:")
|
||||
+ QStringLiteral(" </strong>%7/%8")).arg(values.value(QStringLiteral("width")), values.value(QStringLiteral("height")), values.value(QStringLiteral("frame_rate_num")), values.value(QStringLiteral("frame_rate_den")), values.value(QStringLiteral("sample_aspect_num")), values.value(QStringLiteral("sample_aspect_den")), values.value(QStringLiteral("display_aspect_num")), values.value(QStringLiteral("display_aspect_den")));
|
||||
item->setToolTip(infoString);
|
||||
}
|
||||
|
||||
@@ -825,7 +840,7 @@ void Wizard::slotOpenManual()
|
||||
|
||||
void Wizard::slotShowWebInfos()
|
||||
{
|
||||
KRun::runUrl(QUrl("http://kdenlive.org/discover/" + QString(kdenlive_version).section(' ', 0, 0)), QStringLiteral("text/html"), this);
|
||||
KRun::runUrl(QUrl("http://kdenlive.org/discover/" + QString(kdenlive_version).section(QLatin1Char(' '), 0, 0)), QStringLiteral("text/html"), this);
|
||||
}
|
||||
|
||||
void Wizard::slotSaveCaptureFormat()
|
||||
@@ -846,14 +861,14 @@ void Wizard::slotSaveCaptureFormat()
|
||||
profile.frame_rate_num = format.at(3).toInt();
|
||||
profile.frame_rate_den = format.at(4).toInt();
|
||||
profile.progressive = 1;
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/profiles/");
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/profiles/"));
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(QStringLiteral("."));
|
||||
}
|
||||
ProfilesDialog::saveProfile(profile, dir.absoluteFilePath(QStringLiteral("video4linux")));
|
||||
}
|
||||
|
||||
void Wizard::slotUpdateDecklinkDevice(int captureCard)
|
||||
void Wizard::slotUpdateDecklinkDevice(uint captureCard)
|
||||
{
|
||||
KdenliveSettings::setDecklink_capturedevice(captureCard);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ class KMessageWidget;
|
||||
class MyWizardPage : public QWizardPage
|
||||
{
|
||||
public:
|
||||
explicit MyWizardPage(QWidget *parent = Q_NULLPTR);
|
||||
explicit MyWizardPage(QWidget *parent = nullptr);
|
||||
void setComplete(bool complete);
|
||||
bool isComplete() const Q_DECL_OVERRIDE;
|
||||
bool m_isComplete;
|
||||
@@ -45,7 +45,7 @@ class Wizard : public QWizard
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit Wizard(bool autoClose, QWidget *parent = Q_NULLPTR);
|
||||
explicit Wizard(bool autoClose, QWidget *parent = nullptr);
|
||||
void installExtraMimes(const QString &baseName, const QStringList &globs);
|
||||
void runUpdateMimeDatabase();
|
||||
void adjustSettings();
|
||||
@@ -80,7 +80,7 @@ private slots:
|
||||
void slotDetectWebcam();
|
||||
void slotUpdateCaptureParameters();
|
||||
void slotSaveCaptureFormat();
|
||||
void slotUpdateDecklinkDevice(int captureCard);
|
||||
void slotUpdateDecklinkDevice(uint captureCard);
|
||||
void slotOpenManual();
|
||||
};
|
||||
|
||||
|
||||
@@ -64,8 +64,6 @@ DocumentChecker::DocumentChecker(const QUrl &url, const QDomDocument &doc):
|
||||
|
||||
bool DocumentChecker::hasErrorInClips()
|
||||
{
|
||||
QDomElement e;
|
||||
QString resource;
|
||||
int max;
|
||||
QDomElement baseElement = m_doc.documentElement();
|
||||
QString root = baseElement.attribute(QStringLiteral("root"));
|
||||
@@ -129,7 +127,7 @@ bool DocumentChecker::hasErrorInClips()
|
||||
QStringList serviceToCheck;
|
||||
serviceToCheck << QStringLiteral("kdenlivetitle") << QStringLiteral("qimage") << QStringLiteral("pixbuf") << QStringLiteral("timewarp") << QStringLiteral("framebuffer") << QStringLiteral("xml");
|
||||
for (int i = 0; i < max; ++i) {
|
||||
e = documentProducers.item(i).toElement();
|
||||
QDomElement e = documentProducers.item(i).toElement();
|
||||
QString service = EffectsList::property(e, QStringLiteral("mlt_service"));
|
||||
if (!service.startsWith(QLatin1String("avformat")) && !serviceToCheck.contains(service)) {
|
||||
continue;
|
||||
@@ -147,7 +145,7 @@ bool DocumentChecker::hasErrorInClips()
|
||||
checkMissingImagesAndFonts(images, fonts, e.attribute(QStringLiteral("id")), e.attribute(QStringLiteral("name")));
|
||||
continue;
|
||||
}
|
||||
resource = EffectsList::property(e, QStringLiteral("resource"));
|
||||
QString resource = EffectsList::property(e, QStringLiteral("resource"));
|
||||
if (resource.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
@@ -194,7 +192,7 @@ bool DocumentChecker::hasErrorInClips()
|
||||
original.prepend(root);
|
||||
}
|
||||
// Check for slideshows
|
||||
bool slideshow = original.contains(QStringLiteral("/.all.")) || original.contains(QStringLiteral("?")) || original.contains(QStringLiteral("%"));
|
||||
bool slideshow = original.contains(QStringLiteral("/.all.")) || original.contains(QLatin1Char('?')) || original.contains(QLatin1Char('%'));
|
||||
if (slideshow && !EffectsList::property(e, QStringLiteral("ttl")).isEmpty()) {
|
||||
original = QFileInfo(original).absolutePath();
|
||||
}
|
||||
@@ -206,7 +204,7 @@ bool DocumentChecker::hasErrorInClips()
|
||||
continue;
|
||||
}
|
||||
// Check for slideshows
|
||||
bool slideshow = resource.contains(QStringLiteral("/.all.")) || resource.contains(QStringLiteral("?")) || resource.contains(QStringLiteral("%"));
|
||||
bool slideshow = resource.contains(QStringLiteral("/.all.")) || resource.contains(QLatin1Char('?')) || resource.contains(QLatin1Char('%'));
|
||||
if ((service == QLatin1String("qimage") || service == QLatin1String("pixbuf")) && slideshow) {
|
||||
resource = QFileInfo(resource).absolutePath();
|
||||
}
|
||||
@@ -249,7 +247,7 @@ bool DocumentChecker::hasErrorInClips()
|
||||
QString fixedLuma;
|
||||
// check if this was an old format luma, not in correct folder
|
||||
fixedLuma = filePath.section(QLatin1Char('/'), 0, -2);
|
||||
fixedLuma.append(hdProfile ? "/HD/" : "/PAL/");
|
||||
fixedLuma.append(hdProfile ? QStringLiteral("/HD/") : QStringLiteral("/PAL/"));
|
||||
fixedLuma.append(filePath.section(QLatin1Char('/'), -1));
|
||||
if (QFile::exists(fixedLuma)) {
|
||||
// Auto replace pgm with png for lumas
|
||||
@@ -257,9 +255,9 @@ bool DocumentChecker::hasErrorInClips()
|
||||
continue;
|
||||
}
|
||||
if (filePath.endsWith(QLatin1String(".pgm"))) {
|
||||
fixedLuma = filePath.section(QLatin1Char('.') , 0, -2) + ".png";
|
||||
fixedLuma = filePath.section(QLatin1Char('.') , 0, -2) + QStringLiteral(".png");
|
||||
} else if (filePath.endsWith(QLatin1String(".png"))) {
|
||||
fixedLuma = filePath.section(QLatin1Char('.'), 0, -2) + ".pgm";
|
||||
fixedLuma = filePath.section(QLatin1Char('.'), 0, -2) + QStringLiteral(".pgm");
|
||||
}
|
||||
if (!fixedLuma.isEmpty() && QFile::exists(fixedLuma)) {
|
||||
// Auto replace pgm with png for lumas
|
||||
@@ -280,7 +278,7 @@ bool DocumentChecker::hasErrorInClips()
|
||||
luma = getProperty(transition, QStringLiteral("luma"));
|
||||
}
|
||||
if (!luma.isEmpty() && autoFixLuma.contains(luma)) {
|
||||
setProperty(transition, service == QLatin1String("luma") ? "resource" : "luma", autoFixLuma.value(luma));
|
||||
setProperty(transition, service == QLatin1String("luma") ? QStringLiteral("resource") : QStringLiteral("luma"), autoFixLuma.value(luma));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -303,15 +301,15 @@ bool DocumentChecker::hasErrorInClips()
|
||||
max = m_missingClips.count();
|
||||
m_missingProxyIds.clear();
|
||||
for (int i = 0; i < max; ++i) {
|
||||
e = m_missingClips.at(i).toElement();
|
||||
QDomElement e = m_missingClips.at(i).toElement();
|
||||
QString clipType;
|
||||
ClipType type;
|
||||
int status = CLIPMISSING;
|
||||
const QString service = EffectsList::property(e, QStringLiteral("mlt_service"));
|
||||
const QString service = EffectsList::property(e, QStringLiteral("mlt_service"));
|
||||
QString resource = service == QLatin1String("timewarp") ? EffectsList::property(e, QStringLiteral("warp_resource")) : EffectsList::property(e, QStringLiteral("resource"));
|
||||
bool slideshow = resource.contains(QStringLiteral("/.all.")) || resource.contains(QStringLiteral("?")) || resource.contains(QStringLiteral("%"));
|
||||
if (service == QLatin1String("avformat") || service == QLatin1String("avformat-novalidate") || service == QLatin1String("framebuffer") || service == QLatin1String("timewarp")) {
|
||||
clipType = i18n("Video clip");
|
||||
bool slideshow = resource.contains(QStringLiteral("/.all.")) || resource.contains(QLatin1Char('?')) || resource.contains(QLatin1Char('%'));
|
||||
if (service == QLatin1String("avformat") || service == QLatin1String("avformat-novalidate") || service == QLatin1String("framebuffer") || service == QLatin1String("timewarp")) {
|
||||
clipType = i18n("Video clip");
|
||||
type = AV;
|
||||
} else if (service == QLatin1String("qimage") || service == QLatin1String("pixbuf")) {
|
||||
if (slideshow) {
|
||||
@@ -375,30 +373,30 @@ bool DocumentChecker::hasErrorInClips()
|
||||
}
|
||||
}
|
||||
|
||||
foreach (const QString &font, m_missingFonts) {
|
||||
//TODO the following loop is disabled because m_missingFonts is cleared (line 124), but not filled, that looks suspicious
|
||||
/*foreach (const QString &font, m_missingFonts) {
|
||||
QString clipType = i18n("Title Font");
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.treeWidget, QStringList() << clipType);
|
||||
item->setData(0, statusRole, CLIPPLACEHOLDER);
|
||||
item->setIcon(0, KoIconUtils::themedIcon(QStringLiteral("dialog-warning")));
|
||||
item->setToolTip(1, e.attribute(QStringLiteral("name")));
|
||||
QString ft = e.attribute(QStringLiteral("resource"));
|
||||
QString newft = QFontInfo(QFont(ft)).family();
|
||||
item->setText(1, i18n("%1 will be replaced by %2", ft, newft));
|
||||
QString newft = QFontInfo(QFont(font)).family();
|
||||
item->setText(1, i18n("%1 will be replaced by %2", font, newft));
|
||||
item->setData(0, typeRole, CLIPMISSING);
|
||||
}
|
||||
}*/
|
||||
|
||||
if (!m_missingClips.isEmpty()) {
|
||||
m_ui.infoLabel->setText(i18n("The project file contains missing clips or files"));
|
||||
}
|
||||
if (!missingProxies.isEmpty()) {
|
||||
if (!m_ui.infoLabel->text().isEmpty()) {
|
||||
m_ui.infoLabel->setText(m_ui.infoLabel->text() + ". ");
|
||||
m_ui.infoLabel->setText(m_ui.infoLabel->text() + QStringLiteral(". "));
|
||||
}
|
||||
m_ui.infoLabel->setText(m_ui.infoLabel->text() + i18n("Missing proxies will be recreated after opening."));
|
||||
}
|
||||
if (!missingSources.isEmpty()) {
|
||||
if (!m_ui.infoLabel->text().isEmpty()) {
|
||||
m_ui.infoLabel->setText(m_ui.infoLabel->text() + ". ");
|
||||
m_ui.infoLabel->setText(m_ui.infoLabel->text() + QStringLiteral(". "));
|
||||
}
|
||||
m_ui.infoLabel->setText(m_ui.infoLabel->text() + i18np("The project file contains a missing clip, you can still work with its proxy.", "The project file contains %1 missing clips, you can still work with their proxies.", missingSources.count()));
|
||||
}
|
||||
@@ -419,16 +417,14 @@ bool DocumentChecker::hasErrorInClips()
|
||||
}
|
||||
|
||||
for (int i = 0; i < max; ++i) {
|
||||
e = missingProxies.at(i).toElement();
|
||||
QDomElement e = missingProxies.at(i).toElement();
|
||||
QString realPath = EffectsList::property(e, QStringLiteral("kdenlive:originalurl"));
|
||||
QString id = e.attribute(QStringLiteral("id"));
|
||||
m_missingProxyIds << id;
|
||||
// Tell Kdenlive to recreate proxy
|
||||
e.setAttribute(QStringLiteral("_replaceproxy"), QStringLiteral("1"));
|
||||
// Replace proxy url with real clip in MLT producers
|
||||
QDomNodeList properties;
|
||||
QDomElement mltProd;
|
||||
QDomElement property;
|
||||
int prodsCount = documentProducers.count();
|
||||
for (int j = 0; j < prodsCount; ++j) {
|
||||
mltProd = documentProducers.at(j).toElement();
|
||||
@@ -437,17 +433,17 @@ bool DocumentChecker::hasErrorInClips()
|
||||
bool slowmotion = false;
|
||||
if (parentId.startsWith(QLatin1String("slowmotion"))) {
|
||||
slowmotion = true;
|
||||
parentId = parentId.section(':', 1, 1);
|
||||
parentId = parentId.section(QLatin1Char(':'), 1, 1);
|
||||
}
|
||||
if (parentId.contains('_')) {
|
||||
parentId = parentId.section('_', 0, 0);
|
||||
if (parentId.contains(QLatin1Char('_'))) {
|
||||
parentId = parentId.section(QLatin1Char('_'), 0, 0);
|
||||
}
|
||||
if (parentId == id) {
|
||||
// Hit, we must replace url
|
||||
QString suffix;
|
||||
QString resource = EffectsList::property(mltProd, QStringLiteral("resource"));
|
||||
if (slowmotion) {
|
||||
suffix = '?' + resource.section('?', -1);
|
||||
suffix = QLatin1Char('?') + resource.section(QLatin1Char('?'), -1);
|
||||
}
|
||||
EffectsList::setProperty(mltProd, QStringLiteral("resource"), realPath + suffix);
|
||||
if (prodId == id) {
|
||||
@@ -473,7 +469,7 @@ bool DocumentChecker::hasErrorInClips()
|
||||
item->setData(0, statusRole, SOURCEMISSING);
|
||||
item->setToolTip(0, i18n("Missing source clip"));
|
||||
for (int i = 0; i < max; ++i) {
|
||||
e = missingSources.at(i).toElement();
|
||||
QDomElement e = missingSources.at(i).toElement();
|
||||
QString realPath = EffectsList::property(e, QStringLiteral("kdenlive:originalurl"));
|
||||
QString id = e.attribute(QStringLiteral("id"));
|
||||
// Tell Kdenlive the source is missing
|
||||
@@ -581,7 +577,7 @@ void DocumentChecker::slotSearchClips()
|
||||
if (!clipPath.isEmpty()) {
|
||||
fixed = true;
|
||||
child->setText(1, clipPath);
|
||||
child->setIcon(0, perfectMatch ? KoIconUtils::themedIcon("dialog-ok") : KoIconUtils::themedIcon("dialog-warning"));
|
||||
child->setIcon(0, perfectMatch ? KoIconUtils::themedIcon(QStringLiteral("dialog-ok")) : KoIconUtils::themedIcon(QStringLiteral("dialog-warning")));
|
||||
child->setData(0, statusRole, CLIPOK);
|
||||
}
|
||||
} else if (child->data(0, statusRole).toInt() == LUMAMISSING) {
|
||||
@@ -631,13 +627,17 @@ QString DocumentChecker::searchLuma(const QDir &dir, const QString &file) const
|
||||
}
|
||||
// try to find luma in application path
|
||||
searchPath.setPath(QCoreApplication::applicationDirPath());
|
||||
#ifdef Q_OS_WIN
|
||||
searchPath.cd(QStringLiteral("data/lumas"));
|
||||
#else
|
||||
searchPath.cd(QStringLiteral("../share/apps/kdenlive/lumas"));
|
||||
#endif
|
||||
result.setFile(searchPath, fname);
|
||||
if (result.exists()) {
|
||||
return result.filePath();
|
||||
}
|
||||
// Try in Kdenlive's standard KDE path
|
||||
QString res = QStandardPaths::locate(QStandardPaths::AppDataLocation, "lumas/" + fname);
|
||||
QString res = QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("lumas/") + fname);
|
||||
if (!res.isEmpty()) {
|
||||
return res;
|
||||
}
|
||||
@@ -651,7 +651,7 @@ QString DocumentChecker::searchPathRecursively(const QDir &dir, const QString &f
|
||||
QStringList filters;
|
||||
if (type == SlideShow) {
|
||||
if (fileName.contains(QLatin1Char('%'))) {
|
||||
filters << fileName.section(QLatin1Char('%'), 0, -2) + QStringLiteral("*");
|
||||
filters << fileName.section(QLatin1Char('%'), 0, -2) + QLatin1Char('*');
|
||||
} else {
|
||||
return QString();
|
||||
}
|
||||
@@ -706,7 +706,7 @@ QString DocumentChecker::searchFileRecursively(const QDir &dir, const QString &m
|
||||
}
|
||||
file.close();
|
||||
fileHash = QCryptographicHash::hash(fileData, QCryptographicHash::Md5);
|
||||
if (QString(fileHash.toHex()) == matchHash) {
|
||||
if (QString::fromLatin1(fileHash.toHex()) == matchHash) {
|
||||
return file.fileName();
|
||||
}
|
||||
}
|
||||
@@ -795,16 +795,16 @@ void DocumentChecker::fixProxyClip(const QString &id, const QString &oldUrl, con
|
||||
for (int i = 0; i < producers.count(); ++i) {
|
||||
e = producers.item(i).toElement();
|
||||
QString sourceId = e.attribute(QStringLiteral("id"));
|
||||
QString parentId = sourceId.section('_', 0, 0);
|
||||
QString parentId = sourceId.section(QLatin1Char('_'), 0, 0);
|
||||
if (parentId.startsWith(QLatin1String("slowmotion"))) {
|
||||
parentId = parentId.section(':', 1, 1);
|
||||
parentId = parentId.section(QLatin1Char(':'), 1, 1);
|
||||
}
|
||||
if (parentId == id) {
|
||||
// Fix clip
|
||||
QString resource = EffectsList::property(e, QStringLiteral("resource"));
|
||||
// TODO: Slowmmotion clips
|
||||
if (resource.contains(QRegExp("\\?[0-9]+\\.[0-9]+(&strobe=[0-9]+)?$"))) {
|
||||
//fixedResource.append('?' + resource.section('?', -1));
|
||||
if (resource.contains(QRegExp(QStringLiteral("\\?[0-9]+\\.[0-9]+(&strobe=[0-9]+)?$")))) {
|
||||
//fixedResource.append(QLatin1Char('?') + resource.section(QLatin1Char('?'), -1));
|
||||
}
|
||||
if (resource == oldUrl) {
|
||||
EffectsList::setProperty(e, QStringLiteral("resource"), newUrl);
|
||||
@@ -827,16 +827,16 @@ void DocumentChecker::fixSourceClipItem(QTreeWidgetItem *child, const QDomNodeLi
|
||||
for (int i = 0; i < producers.count(); ++i) {
|
||||
e = producers.item(i).toElement();
|
||||
QString sourceId = e.attribute(QStringLiteral("id"));
|
||||
QString parentId = sourceId.section('_', 0, 0);
|
||||
QString parentId = sourceId.section(QLatin1Char('_'), 0, 0);
|
||||
if (parentId.startsWith(QLatin1String("slowmotion"))) {
|
||||
parentId = parentId.section(':', 1, 1);
|
||||
parentId = parentId.section(QLatin1Char(':'), 1, 1);
|
||||
}
|
||||
if (parentId == id) {
|
||||
// Fix clip
|
||||
QString resource = EffectsList::property(e, QStringLiteral("resource"));
|
||||
QString fixedResource = child->text(1);
|
||||
if (resource.contains(QRegExp("\\?[0-9]+\\.[0-9]+(&strobe=[0-9]+)?$"))) {
|
||||
fixedResource.append('?' + resource.section('?', -1));
|
||||
if (resource.contains(QRegExp(QStringLiteral("\\?[0-9]+\\.[0-9]+(&strobe=[0-9]+)?$")))) {
|
||||
fixedResource.append(QLatin1Char('?') + resource.section(QLatin1Char('?'), -1));
|
||||
}
|
||||
if (sourceId == id) {
|
||||
// Only set originalurl on master producer
|
||||
@@ -863,7 +863,7 @@ void DocumentChecker::fixClipItem(QTreeWidgetItem *child, const QDomNodeList &pr
|
||||
// edit images embedded in titles
|
||||
for (int i = 0; i < producers.count(); ++i) {
|
||||
e = producers.item(i).toElement();
|
||||
if (e.attribute(QStringLiteral("id")).section('_', 0, 0) == id) {
|
||||
if (e.attribute(QStringLiteral("id")).section(QLatin1Char('_'), 0, 0) == id) {
|
||||
// Fix clip
|
||||
properties = e.childNodes();
|
||||
for (int j = 0; j < properties.count(); ++j) {
|
||||
@@ -891,17 +891,17 @@ void DocumentChecker::fixClipItem(QTreeWidgetItem *child, const QDomNodeList &pr
|
||||
}*/
|
||||
for (int i = 0; i < producers.count(); ++i) {
|
||||
e = producers.item(i).toElement();
|
||||
if (e.attribute(QStringLiteral("id")).section('_', 0, 0) == id || e.attribute(QStringLiteral("id")).section(':', 1, 1) == id || e.attribute(QStringLiteral("id")) == id) {
|
||||
if (e.attribute(QStringLiteral("id")).section(QLatin1Char('_'), 0, 0) == id || e.attribute(QStringLiteral("id")).section(QLatin1Char(':'), 1, 1) == id || e.attribute(QStringLiteral("id")) == id) {
|
||||
// Fix clip
|
||||
QString resource = getProperty(e, QStringLiteral("resource"));
|
||||
QString service = getProperty(e, QStringLiteral("mlt_service"));
|
||||
QString updatedResource = fixedResource;
|
||||
if (resource.contains(QRegExp("\\?[0-9]+\\.[0-9]+(&strobe=[0-9]+)?$"))) {
|
||||
updatedResource.append('?' + resource.section('?', -1));
|
||||
if (resource.contains(QRegExp(QStringLiteral("\\?[0-9]+\\.[0-9]+(&strobe=[0-9]+)?$")))) {
|
||||
updatedResource.append(QLatin1Char('?') + resource.section(QLatin1Char('?'), -1));
|
||||
}
|
||||
if (service == QLatin1String("timewarp")) {
|
||||
setProperty(e, QStringLiteral("warp_resource"), updatedResource);
|
||||
updatedResource.prepend(getProperty(e, QStringLiteral("warp_speed")) + ":");
|
||||
updatedResource.prepend(getProperty(e, QStringLiteral("warp_speed")) + QLatin1Char(':'));
|
||||
}
|
||||
setProperty(e, QStringLiteral("resource"), updatedResource);
|
||||
}
|
||||
@@ -1042,7 +1042,7 @@ void DocumentChecker::slotDeleteSelected()
|
||||
|
||||
for (int i = 0; i < producers.count(); ++i) {
|
||||
e = producers.item(i).toElement();
|
||||
if (deletedIds.contains(e.attribute(QStringLiteral("id")).section('_', 0, 0)) || deletedIds.contains(e.attribute(QStringLiteral("id")).section(':', 1, 1).section('_', 0, 0))) {
|
||||
if (deletedIds.contains(e.attribute(QStringLiteral("id")).section(QLatin1Char('_'), 0, 0)) || deletedIds.contains(e.attribute(QStringLiteral("id")).section(QLatin1Char(':'), 1, 1).section(QLatin1Char('_'), 0, 0))) {
|
||||
// Remove clip
|
||||
mlt.removeChild(e);
|
||||
--i;
|
||||
@@ -1053,7 +1053,7 @@ void DocumentChecker::slotDeleteSelected()
|
||||
QDomNodeList entries = playlists.at(i).toElement().elementsByTagName(QStringLiteral("entry"));
|
||||
for (int j = 0; j < entries.count(); ++j) {
|
||||
e = entries.item(j).toElement();
|
||||
if (deletedIds.contains(e.attribute(QStringLiteral("producer")).section('_', 0, 0)) || deletedIds.contains(e.attribute(QStringLiteral("producer")).section(':', 1, 1).section('_', 0, 0))) {
|
||||
if (deletedIds.contains(e.attribute(QStringLiteral("producer")).section(QLatin1Char('_'), 0, 0)) || deletedIds.contains(e.attribute(QStringLiteral("producer")).section(QLatin1Char(':'), 1, 1).section(QLatin1Char('_'), 0, 0))) {
|
||||
// Replace clip with blank
|
||||
while (e.childNodes().count() > 0) {
|
||||
e.removeChild(e.firstChild());
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,8 +26,6 @@
|
||||
#include <QUrl>
|
||||
#include <QMap>
|
||||
|
||||
class QScriptValue;
|
||||
|
||||
class DocumentValidator
|
||||
{
|
||||
|
||||
@@ -51,13 +49,6 @@ private:
|
||||
void checkOrphanedProducers();
|
||||
QStringList getInfoFromEffectName(const QString &oldName);
|
||||
QString colorToString(const QColor &c);
|
||||
/*
|
||||
/// @brief Updates effects that were created using a different version of the underlaying filter than the one installed.
|
||||
void updateEffects();
|
||||
/// @brief Updates the parameters according to the updateRules.
|
||||
/// @see the related in README in effects/update
|
||||
bool updateEffectParameters(const QDomNodeList ¶meters, const QScriptValue *updateRules, const double serviceVersion, const double effectVersion);
|
||||
*/
|
||||
QString factorizeGeomValue(const QString &value, double factor);
|
||||
/** @brief Kdenlive <= 0.9.10 saved title clip item position/opacity with locale which was wrong, fix. */
|
||||
void fixTitleProducerLocale(QDomElement &producer);
|
||||
|
||||
@@ -80,7 +80,7 @@ void DocUndoStack::push(QUndoCommand *cmd)
|
||||
QUndoStack::push(cmd);
|
||||
}
|
||||
|
||||
const double DOCUMENTVERSION = 0.95;
|
||||
const double DOCUMENTVERSION = 0.96;
|
||||
|
||||
KdenliveDoc::KdenliveDoc(const QUrl &url, const QString &projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QMap<QString, QString> &properties, const QMap<QString, QString> &metadata, const QPoint &tracks, Render *render, NotesPlugin *notes, bool *openBackup, MainWindow *parent) :
|
||||
QObject(parent),
|
||||
@@ -122,9 +122,9 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QString &projectFolder, QUndoGro
|
||||
connect(&m_modifiedTimer, &QTimer::timeout, this, &KdenliveDoc::slotProcessModifiedClips);
|
||||
|
||||
// init default document properties
|
||||
m_documentProperties[QStringLiteral("zoom")] = '7';
|
||||
m_documentProperties[QStringLiteral("verticalzoom")] = '1';
|
||||
m_documentProperties[QStringLiteral("zonein")] = '0';
|
||||
m_documentProperties[QStringLiteral("zoom")] = QLatin1Char('7');
|
||||
m_documentProperties[QStringLiteral("verticalzoom")] = QLatin1Char('1');
|
||||
m_documentProperties[QStringLiteral("zonein")] = QLatin1Char('0');
|
||||
m_documentProperties[QStringLiteral("zoneout")] = QStringLiteral("100");
|
||||
m_documentProperties[QStringLiteral("enableproxy")] = QString::number((int) KdenliveSettings::enableproxy());
|
||||
m_documentProperties[QStringLiteral("proxyparams")] = KdenliveSettings::proxyparams();
|
||||
@@ -155,7 +155,7 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QString &projectFolder, QUndoGro
|
||||
systemLocale.setNumberOptions(QLocale::OmitGroupSeparator);
|
||||
QLocale::setDefault(systemLocale);
|
||||
// locale conversion might need to be redone
|
||||
initEffects::parseEffectFiles(pCore->binController()->mltRepository(), setlocale(LC_NUMERIC, nullptr));
|
||||
initEffects::parseEffectFiles(pCore->getMltRepository(), QString::fromLatin1(setlocale(LC_NUMERIC, nullptr)));
|
||||
}
|
||||
*openBackup = false;
|
||||
if (url.isValid()) {
|
||||
@@ -184,12 +184,12 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QString &projectFolder, QUndoGro
|
||||
// Try to recover broken file produced by Kdenlive 0.9.4
|
||||
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
int correction = 0;
|
||||
QString playlist = file.readAll();
|
||||
QString playlist = QString::fromUtf8(file.readAll());
|
||||
while (!success && correction < 2) {
|
||||
int errorPos = 0;
|
||||
line--;
|
||||
col = col - 2;
|
||||
for (int j = 0; j < line && errorPos < playlist.length(); ++j) {
|
||||
for (int k = 0; k < line && errorPos < playlist.length(); ++k) {
|
||||
errorPos = playlist.indexOf(QLatin1Char('\n'), errorPos);
|
||||
errorPos++;
|
||||
}
|
||||
@@ -439,16 +439,16 @@ QDomDocument KdenliveDoc::createEmptyDocument(const QList<TrackInfo> &tracks)
|
||||
// The lower video track will receive composite transitions
|
||||
int lowestVideoTrack = -1;
|
||||
for (int i = 0; i < total; ++i) {
|
||||
QDomElement playlist = doc.createElement(QStringLiteral("playlist"));
|
||||
playlist.setAttribute(QStringLiteral("id"), "playlist" + QString::number(i + 1));
|
||||
playlist.setAttribute(QStringLiteral("kdenlive:track_name"), tracks.at(i).trackName);
|
||||
QDomElement cur_playlist = doc.createElement(QStringLiteral("playlist"));
|
||||
cur_playlist.setAttribute(QStringLiteral("id"), QStringLiteral("playlist") + QString::number(i + 1));
|
||||
cur_playlist.setAttribute(QStringLiteral("kdenlive:track_name"), tracks.at(i).trackName);
|
||||
if (tracks.at(i).type == AudioTrack) {
|
||||
playlist.setAttribute(QStringLiteral("kdenlive:audio_track"), 1);
|
||||
cur_playlist.setAttribute(QStringLiteral("kdenlive:audio_track"), 1);
|
||||
} else if (lowestVideoTrack == -1) {
|
||||
// Register first video track
|
||||
lowestVideoTrack = i + 1;
|
||||
}
|
||||
mlt.appendChild(playlist);
|
||||
mlt.appendChild(cur_playlist);
|
||||
}
|
||||
QString compositeService = TransitionHandler::compositeTransition();
|
||||
QDomElement track0 = doc.createElement(QStringLiteral("track"));
|
||||
@@ -458,7 +458,7 @@ QDomDocument KdenliveDoc::createEmptyDocument(const QList<TrackInfo> &tracks)
|
||||
// create audio and video tracks
|
||||
for (int i = 0; i < total; ++i) {
|
||||
QDomElement track = doc.createElement(QStringLiteral("track"));
|
||||
track.setAttribute(QStringLiteral("producer"), "playlist" + QString::number(i + 1));
|
||||
track.setAttribute(QStringLiteral("producer"), QStringLiteral("playlist") + QString::number(i + 1));
|
||||
if (tracks.at(i).type == AudioTrack) {
|
||||
track.setAttribute(QStringLiteral("hide"), QStringLiteral("video"));
|
||||
} else if (tracks.at(i).isBlind) {
|
||||
@@ -479,60 +479,64 @@ QDomDocument KdenliveDoc::createEmptyDocument(const QList<TrackInfo> &tracks)
|
||||
QDomElement transition = doc.createElement(QStringLiteral("transition"));
|
||||
transition.setAttribute(QStringLiteral("always_active"), QStringLiteral("1"));
|
||||
|
||||
QDomElement property = doc.createElement(QStringLiteral("property"));
|
||||
property.setAttribute(QStringLiteral("name"), QStringLiteral("mlt_service"));
|
||||
QDomElement cur_property = doc.createElement(QStringLiteral("property"));
|
||||
cur_property.setAttribute(QStringLiteral("name"), QStringLiteral("mlt_service"));
|
||||
value = doc.createTextNode(QStringLiteral("mix"));
|
||||
property.appendChild(value);
|
||||
transition.appendChild(property);
|
||||
cur_property.appendChild(value);
|
||||
transition.appendChild(cur_property);
|
||||
|
||||
property = doc.createElement(QStringLiteral("property"));
|
||||
property.setAttribute(QStringLiteral("name"), QStringLiteral("a_track"));
|
||||
QDomText value = doc.createTextNode(QStringLiteral("0"));
|
||||
property.appendChild(value);
|
||||
transition.appendChild(property);
|
||||
cur_property = doc.createElement(QStringLiteral("property"));
|
||||
cur_property.setAttribute(QStringLiteral("name"), QStringLiteral("a_track"));
|
||||
value = doc.createTextNode(QStringLiteral("0"));
|
||||
cur_property.appendChild(value);
|
||||
transition.appendChild(cur_property);
|
||||
|
||||
property = doc.createElement(QStringLiteral("property"));
|
||||
property.setAttribute(QStringLiteral("name"), QStringLiteral("b_track"));
|
||||
cur_property = doc.createElement(QStringLiteral("property"));
|
||||
cur_property.setAttribute(QStringLiteral("name"), QStringLiteral("b_track"));
|
||||
value = doc.createTextNode(QString::number(i));
|
||||
property.appendChild(value);
|
||||
transition.appendChild(property);
|
||||
cur_property.appendChild(value);
|
||||
transition.appendChild(cur_property);
|
||||
|
||||
property = doc.createElement(QStringLiteral("property"));
|
||||
property.setAttribute(QStringLiteral("name"), QStringLiteral("combine"));
|
||||
cur_property = doc.createElement(QStringLiteral("property"));
|
||||
if (TransitionHandler::sumAudioMixAvailable()) {
|
||||
cur_property.setAttribute(QStringLiteral("name"), QStringLiteral("sum"));
|
||||
} else {
|
||||
cur_property.setAttribute(QStringLiteral("name"), QStringLiteral("combine"));
|
||||
}
|
||||
value = doc.createTextNode(QStringLiteral("1"));
|
||||
property.appendChild(value);
|
||||
transition.appendChild(property);
|
||||
cur_property.appendChild(value);
|
||||
transition.appendChild(cur_property);
|
||||
|
||||
property = doc.createElement(QStringLiteral("property"));
|
||||
property.setAttribute(QStringLiteral("name"), QStringLiteral("internal_added"));
|
||||
cur_property = doc.createElement(QStringLiteral("property"));
|
||||
cur_property.setAttribute(QStringLiteral("name"), QStringLiteral("internal_added"));
|
||||
value = doc.createTextNode(QStringLiteral("237"));
|
||||
property.appendChild(value);
|
||||
transition.appendChild(property);
|
||||
cur_property.appendChild(value);
|
||||
transition.appendChild(cur_property);
|
||||
|
||||
tractor.appendChild(transition);
|
||||
}
|
||||
if (i > 0 && tracks.at(i - 1).type == VideoTrack) {
|
||||
// Only add composite transition if both tracks are video
|
||||
QDomElement transition = doc.createElement(QStringLiteral("transition"));
|
||||
property = doc.createElement(QStringLiteral("property"));
|
||||
property.setAttribute(QStringLiteral("name"), QStringLiteral("mlt_service"));
|
||||
property.appendChild(doc.createTextNode(compositeService));
|
||||
transition.appendChild(property);
|
||||
QDomElement cur_property = doc.createElement(QStringLiteral("property"));
|
||||
cur_property.setAttribute(QStringLiteral("name"), QStringLiteral("mlt_service"));
|
||||
cur_property.appendChild(doc.createTextNode(compositeService));
|
||||
transition.appendChild(cur_property);
|
||||
|
||||
property = doc.createElement(QStringLiteral("property"));
|
||||
property.setAttribute(QStringLiteral("name"), QStringLiteral("a_track"));
|
||||
property.appendChild(doc.createTextNode(QString::number(0)));
|
||||
transition.appendChild(property);
|
||||
cur_property = doc.createElement(QStringLiteral("property"));
|
||||
cur_property.setAttribute(QStringLiteral("name"), QStringLiteral("a_track"));
|
||||
cur_property.appendChild(doc.createTextNode(QString::number(0)));
|
||||
transition.appendChild(cur_property);
|
||||
|
||||
property = doc.createElement(QStringLiteral("property"));
|
||||
property.setAttribute(QStringLiteral("name"), QStringLiteral("b_track"));
|
||||
property.appendChild(doc.createTextNode(QString::number(i)));
|
||||
transition.appendChild(property);
|
||||
cur_property = doc.createElement(QStringLiteral("property"));
|
||||
cur_property.setAttribute(QStringLiteral("name"), QStringLiteral("b_track"));
|
||||
cur_property.appendChild(doc.createTextNode(QString::number(i)));
|
||||
transition.appendChild(cur_property);
|
||||
|
||||
property = doc.createElement(QStringLiteral("property"));
|
||||
property.setAttribute(QStringLiteral("name"), QStringLiteral("internal_added"));
|
||||
property.appendChild(doc.createTextNode(QStringLiteral("237")));
|
||||
transition.appendChild(property);
|
||||
cur_property = doc.createElement(QStringLiteral("property"));
|
||||
cur_property.setAttribute(QStringLiteral("name"), QStringLiteral("internal_added"));
|
||||
cur_property.appendChild(doc.createTextNode(QStringLiteral("237")));
|
||||
transition.appendChild(cur_property);
|
||||
|
||||
tractor.appendChild(transition);
|
||||
}
|
||||
@@ -707,10 +711,10 @@ bool KdenliveDoc::saveSceneList(const QString &path, const QString &scene)
|
||||
file.close();
|
||||
cleanupBackupFiles();
|
||||
QFileInfo info(file);
|
||||
QString fileName = QUrl::fromLocalFile(path).fileName().section('.', 0, -2);
|
||||
fileName.append('-' + m_documentProperties.value(QStringLiteral("documentid")));
|
||||
QString fileName = QUrl::fromLocalFile(path).fileName().section(QLatin1Char('.'), 0, -2);
|
||||
fileName.append(QLatin1Char('-') + m_documentProperties.value(QStringLiteral("documentid")));
|
||||
fileName.append(info.lastModified().toString(QStringLiteral("-yyyy-MM-dd-hh-mm")));
|
||||
fileName.append(".kdenlive.png");
|
||||
fileName.append(QStringLiteral(".kdenlive.png"));
|
||||
QDir backupFolder(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/.backup"));
|
||||
emit saveTimelinePreview(backupFolder.absoluteFilePath(fileName));
|
||||
return true;
|
||||
@@ -787,7 +791,7 @@ void KdenliveDoc::moveProjectData(const QString &/*src*/, const QString &dest)
|
||||
}
|
||||
}
|
||||
if (!cacheUrls.isEmpty()) {
|
||||
QDir proxyDir(dest + "/proxy/");
|
||||
QDir proxyDir(dest + QStringLiteral("/proxy/"));
|
||||
if (proxyDir.mkpath(QStringLiteral("."))) {
|
||||
KIO::CopyJob *job = KIO::move(cacheUrls, QUrl::fromLocalFile(proxyDir.absolutePath()));
|
||||
KJobWidgets::setWindow(job, QApplication::activeWindow());
|
||||
@@ -916,9 +920,9 @@ bool KdenliveDoc::isModified() const
|
||||
const QString KdenliveDoc::description() const
|
||||
{
|
||||
if (!m_url.isValid()) {
|
||||
return i18n("Untitled") + "[*] / " + m_profile.description;
|
||||
return i18n("Untitled") + QStringLiteral("[*] / ") + m_profile.description;
|
||||
} else {
|
||||
return m_url.fileName() + " [*]/ " + m_profile.description;
|
||||
return m_url.fileName() + QStringLiteral(" [*]/ ") + m_profile.description;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -946,7 +950,7 @@ QString KdenliveDoc::searchFileRecursively(const QDir &dir, const QString &match
|
||||
}
|
||||
file.close();
|
||||
fileHash = QCryptographicHash::hash(fileData, QCryptographicHash::Md5);
|
||||
if (QString(fileHash.toHex()) == matchHash) {
|
||||
if (QString::fromLatin1(fileHash.toHex()) == matchHash) {
|
||||
return file.fileName();
|
||||
} else {
|
||||
qCDebug(KDENLIVE_LOG) << filesAndDirs.at(i) << "size match but not hash";
|
||||
@@ -991,7 +995,7 @@ ClipController *KdenliveDoc::getClipController(const QString &clipId)
|
||||
|
||||
void KdenliveDoc::slotCreateTextTemplateClip(const QString &group, const QString &groupId, QUrl path)
|
||||
{
|
||||
QString titlesFolder = QDir::cleanPath(m_projectFolder + "/titles/");
|
||||
QString titlesFolder = QDir::cleanPath(m_projectFolder + QStringLiteral("/titles/"));
|
||||
if (path.isEmpty()) {
|
||||
QPointer<QFileDialog> d = new QFileDialog(QApplication::activeWindow(), i18n("Enter Template Path"), titlesFolder);
|
||||
d->setMimeTypeFilters(QStringList() << QStringLiteral("application/x-kdenlivetitle"));
|
||||
@@ -1016,7 +1020,7 @@ void KdenliveDoc::cacheImage(const QString &fileId, const QImage &img) const
|
||||
bool ok = false;
|
||||
QDir dir = getCacheDir(CacheThumbs, &ok);
|
||||
if (ok) {
|
||||
img.save(dir.absoluteFilePath(fileId + ".png"));
|
||||
img.save(dir.absoluteFilePath(fileId + QStringLiteral(".png")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1041,7 +1045,16 @@ QMap<QString, QString> KdenliveDoc::getRenderProperties() const
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (i.key().startsWith(QLatin1String("render"))) {
|
||||
renderProperties.insert(i.key(), i.value());
|
||||
if (i.key() == QLatin1String("renderurl")) {
|
||||
// Check that we have a full path
|
||||
QString value = i.value();
|
||||
if (QFileInfo(value).isRelative()) {
|
||||
value.prepend(pCore->binController()->documentRoot());
|
||||
}
|
||||
renderProperties.insert(i.key(), value);
|
||||
} else {
|
||||
renderProperties.insert(i.key(), i.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
return renderProperties;
|
||||
@@ -1061,8 +1074,8 @@ void KdenliveDoc::saveCustomEffects(const QDomNodeList &customeffects)
|
||||
if (MainWindow::customEffects.hasEffect(tag, id) == -1) {
|
||||
QDomDocument doc;
|
||||
doc.appendChild(doc.importNode(e, true));
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/effects";
|
||||
path += id + ".xml";
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/effects");
|
||||
path += id + QStringLiteral(".xml");
|
||||
if (!QFile::exists(path)) {
|
||||
importedEffects << id;
|
||||
QFile file(path);
|
||||
@@ -1089,7 +1102,7 @@ void KdenliveDoc::updateProjectFolderPlacesEntry()
|
||||
* http://websvn.kde.org/trunk/KDE/kdelibs/kfile/kfileplacesmodel.cpp?view=markup
|
||||
*/
|
||||
|
||||
const QString file = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/user-places.xbel";
|
||||
const QString file = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/user-places.xbel");
|
||||
KBookmarkManager *bookmarkManager = KBookmarkManager::managerForExternalFile(file);
|
||||
if (!bookmarkManager) {
|
||||
return;
|
||||
@@ -1173,11 +1186,11 @@ void KdenliveDoc::backupLastSavedVersion(const QString &path)
|
||||
}
|
||||
QFile file(path);
|
||||
QDir backupFolder(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/.backup"));
|
||||
QString fileName = QUrl::fromLocalFile(path).fileName().section('.', 0, -2);
|
||||
QString fileName = QUrl::fromLocalFile(path).fileName().section(QLatin1Char('.'), 0, -2);
|
||||
QFileInfo info(file);
|
||||
fileName.append('-' + m_documentProperties.value(QStringLiteral("documentid")));
|
||||
fileName.append(QLatin1Char('-') + m_documentProperties.value(QStringLiteral("documentid")));
|
||||
fileName.append(info.lastModified().toString(QStringLiteral("-yyyy-MM-dd-hh-mm")));
|
||||
fileName.append(".kdenlive");
|
||||
fileName.append(QStringLiteral(".kdenlive"));
|
||||
QString backupFile = backupFolder.absoluteFilePath(fileName);
|
||||
if (file.exists()) {
|
||||
// delete previous backup if it was done less than 60 seconds ago
|
||||
@@ -1191,14 +1204,14 @@ void KdenliveDoc::backupLastSavedVersion(const QString &path)
|
||||
void KdenliveDoc::cleanupBackupFiles()
|
||||
{
|
||||
QDir backupFolder(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/.backup"));
|
||||
QString projectFile = url().fileName().section('.', 0, -2);
|
||||
projectFile.append('-' + m_documentProperties.value(QStringLiteral("documentid")));
|
||||
projectFile.append("-??");
|
||||
projectFile.append("??");
|
||||
projectFile.append("-??");
|
||||
projectFile.append("-??");
|
||||
projectFile.append("-??");
|
||||
projectFile.append("-??.kdenlive");
|
||||
QString projectFile = url().fileName().section(QLatin1Char('.'), 0, -2);
|
||||
projectFile.append(QLatin1Char('-') + m_documentProperties.value(QStringLiteral("documentid")));
|
||||
projectFile.append(QStringLiteral("-??"));
|
||||
projectFile.append(QStringLiteral("??"));
|
||||
projectFile.append(QStringLiteral("-??"));
|
||||
projectFile.append(QStringLiteral("-??"));
|
||||
projectFile.append(QStringLiteral("-??"));
|
||||
projectFile.append(QStringLiteral("-??.kdenlive"));
|
||||
|
||||
QStringList filter;
|
||||
filter << projectFile;
|
||||
@@ -1267,22 +1280,22 @@ void KdenliveDoc::cleanupBackupFiles()
|
||||
while (hourList.count() > 0) {
|
||||
f = hourList.takeFirst();
|
||||
QFile::remove(f);
|
||||
QFile::remove(f + ".png");
|
||||
QFile::remove(f + QStringLiteral(".png"));
|
||||
}
|
||||
while (dayList.count() > 0) {
|
||||
f = dayList.takeFirst();
|
||||
QFile::remove(f);
|
||||
QFile::remove(f + ".png");
|
||||
QFile::remove(f + QStringLiteral(".png"));
|
||||
}
|
||||
while (weekList.count() > 0) {
|
||||
f = weekList.takeFirst();
|
||||
QFile::remove(f);
|
||||
QFile::remove(f + ".png");
|
||||
QFile::remove(f + QStringLiteral(".png"));
|
||||
}
|
||||
while (oldList.count() > 0) {
|
||||
f = oldList.takeFirst();
|
||||
QFile::remove(f);
|
||||
QFile::remove(f + ".png");
|
||||
QFile::remove(f + QStringLiteral(".png"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1319,7 +1332,7 @@ void KdenliveDoc::slotProxyCurrentItem(bool doProxy, QList<ProjectClip *> clipLi
|
||||
if (!ok) {
|
||||
// Error
|
||||
}
|
||||
QString extension = QStringLiteral(".") + getDocumentProperty(QStringLiteral("proxyextension"));
|
||||
QString extension = QLatin1Char('.') + getDocumentProperty(QStringLiteral("proxyextension"));
|
||||
QString params = getDocumentProperty(QStringLiteral("proxyparams"));
|
||||
if (params.contains(QStringLiteral("-s "))) {
|
||||
QString proxySize = params.section(QStringLiteral("-s "), 1).section(QStringLiteral("x"), 0, 0);
|
||||
@@ -1389,8 +1402,8 @@ void KdenliveDoc::watchFile(const QString &url)
|
||||
|
||||
void KdenliveDoc::slotClipModified(const QString &path)
|
||||
{
|
||||
QStringList ids = pCore->binController()->getBinIdsByResource(QFileInfo(path));
|
||||
foreach (const QString &id, ids) {
|
||||
const QStringList ids = pCore->binController()->getBinIdsByResource(QFileInfo(path));
|
||||
for (const QString &id : ids) {
|
||||
if (!m_modifiedClips.contains(id)) {
|
||||
pCore->bin()->setWaitingStatus(id);
|
||||
}
|
||||
@@ -1435,7 +1448,7 @@ QMap<QString, QString> KdenliveDoc::documentProperties()
|
||||
m_documentProperties.insert(QStringLiteral("version"), QString::number(DOCUMENTVERSION));
|
||||
m_documentProperties.insert(QStringLiteral("kdenliveversion"), QStringLiteral(KDENLIVE_VERSION));
|
||||
if (!m_projectFolder.isEmpty()) {
|
||||
m_documentProperties.insert(QStringLiteral("storagefolder"), m_projectFolder + QStringLiteral("/") +
|
||||
m_documentProperties.insert(QStringLiteral("storagefolder"), m_projectFolder + QLatin1Char('/') +
|
||||
m_documentProperties.value(QStringLiteral("documentid")));
|
||||
}
|
||||
m_documentProperties.insert(QStringLiteral("profile"), profilePath());
|
||||
@@ -1521,7 +1534,7 @@ void KdenliveDoc::updateProjectProfile(bool reloadProducers)
|
||||
return;
|
||||
}
|
||||
emit updateFps(fpsChanged);
|
||||
if (fpsChanged != 1.0) {
|
||||
if (qAbs(fpsChanged - 1.0) > 1e-6) {
|
||||
pCore->bin()->reloadAllProducers();
|
||||
}
|
||||
}
|
||||
@@ -1605,34 +1618,22 @@ void KdenliveDoc::switchProfile(MltVideoProfile profile, const QString &id, cons
|
||||
// Check profile fps so that we don't end up with an fps = 30.003 which would mess things up
|
||||
QString adjustMessage;
|
||||
double fps = (double)profile.frame_rate_num / profile.frame_rate_den;
|
||||
double fps_int;
|
||||
double fps_frac = std::modf(fps, &fps_int);
|
||||
if (fps_frac < 0.4) {
|
||||
profile.frame_rate_num = (int) fps_int;
|
||||
if (fps - ((int)fps) < 0.4) {
|
||||
profile.frame_rate_num = fps;
|
||||
profile.frame_rate_den = 1;
|
||||
} else if (qAbs(fps - 23.98) < 0.01) {
|
||||
profile.frame_rate_num = 24000;
|
||||
profile.frame_rate_den = 1001;
|
||||
} else if (qAbs(fps - 29.97) < 0.01) {
|
||||
profile.frame_rate_num = 30000;
|
||||
profile.frame_rate_den = 1001;
|
||||
} else if (qAbs(fps - 59.94) < 0.01) {
|
||||
profile.frame_rate_num = 60000;
|
||||
profile.frame_rate_den = 1001;
|
||||
} else {
|
||||
// Check for 23.98, 29.97, 59.94
|
||||
if (fps_int == 23.0) {
|
||||
if (qAbs(fps - 23.98) < 0.01) {
|
||||
profile.frame_rate_num = 24000;
|
||||
profile.frame_rate_den = 1001;
|
||||
}
|
||||
} else if (fps_int == 29.0) {
|
||||
if (qAbs(fps - 29.97) < 0.01) {
|
||||
profile.frame_rate_num = 30000;
|
||||
profile.frame_rate_den = 1001;
|
||||
}
|
||||
} else if (fps_int == 59.0) {
|
||||
if (qAbs(fps - 59.94) < 0.01) {
|
||||
profile.frame_rate_num = 60000;
|
||||
profile.frame_rate_den = 1001;
|
||||
}
|
||||
} else {
|
||||
// Unknown profile fps, warn user
|
||||
adjustMessage = i18n("\nWarning: unknown non integer fps, might cause incorrect duration display.");
|
||||
}
|
||||
adjustMessage = i18n("\nWarning: unknown non integer fps, might cause incorrect duration display.");
|
||||
}
|
||||
if ((double)profile.frame_rate_num / profile.frame_rate_den != fps) {
|
||||
if (qAbs((double)profile.frame_rate_num / profile.frame_rate_den - fps) > 0.01) {
|
||||
adjustMessage = i18n("\nProfile fps adjusted from original %1", QString::number(fps, 'f', 4));
|
||||
}
|
||||
if (KMessageBox::warningContinueCancel(QApplication::activeWindow(), i18n("No profile found for your clip.\nCreate and switch to new profile (%1x%2, %3fps)?%4", profile.width, profile.height, QString::number((double)profile.frame_rate_num / profile.frame_rate_den, 'f', 2), adjustMessage)) == KMessageBox::Continue) {
|
||||
@@ -1734,8 +1735,8 @@ void KdenliveDoc::selectPreviewProfile()
|
||||
setDocumentProperty(QStringLiteral("previewparameters"), bestMatch.section(QLatin1Char(';'), 0, 0));
|
||||
setDocumentProperty(QStringLiteral("previewextension"), bestMatch.section(QLatin1Char(';'), 1, 1));
|
||||
} else {
|
||||
setDocumentProperty(QStringLiteral("previewparameters"), QStringLiteral());
|
||||
setDocumentProperty(QStringLiteral("previewextension"), QStringLiteral());
|
||||
setDocumentProperty(QStringLiteral("previewparameters"), QString());
|
||||
setDocumentProperty(QStringLiteral("previewextension"), QString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1764,7 +1765,7 @@ void KdenliveDoc::initCacheDirs()
|
||||
if (!ok || documentId.isEmpty() || kdenliveCacheDir.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QString basePath = kdenliveCacheDir + "/" + documentId;
|
||||
QString basePath = kdenliveCacheDir + QLatin1Char('/') + documentId;
|
||||
QDir dir(basePath);
|
||||
dir.mkpath(QStringLiteral("."));
|
||||
dir.mkdir(QStringLiteral("preview"));
|
||||
@@ -1790,7 +1791,7 @@ QDir KdenliveDoc::getCacheDir(CacheType type, bool *ok) const
|
||||
// Use specified folder to store all files
|
||||
kdenliveCacheDir = m_projectFolder;
|
||||
}
|
||||
basePath = kdenliveCacheDir + QStringLiteral("/") + documentId;
|
||||
basePath = kdenliveCacheDir + QLatin1Char('/') + documentId;
|
||||
switch (type) {
|
||||
case SystemCacheRoot:
|
||||
return QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#ifndef KDENLIVEDOC_H
|
||||
#define KDENLIVEDOC_H
|
||||
|
||||
#include <QtXml/qdom.h>
|
||||
#include <qdom.h>
|
||||
#include <QMap>
|
||||
#include <QList>
|
||||
#include <QDir>
|
||||
@@ -65,7 +65,7 @@ class DocUndoStack: public QUndoStack
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DocUndoStack(QUndoGroup *parent = Q_NULLPTR);
|
||||
explicit DocUndoStack(QUndoGroup *parent = nullptr);
|
||||
void push(QUndoCommand *cmd);
|
||||
signals:
|
||||
void invalidate();
|
||||
@@ -76,7 +76,7 @@ class KdenliveDoc: public QObject
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
KdenliveDoc(const QUrl &url, const QString &projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QMap<QString, QString> &properties, const QMap<QString, QString> &metadata, const QPoint &tracks, Render *render, NotesPlugin *notes, bool *openBackup, MainWindow *parent = Q_NULLPTR);
|
||||
KdenliveDoc(const QUrl &url, const QString &projectFolder, QUndoGroup *undoGroup, const QString &profileName, const QMap<QString, QString> &properties, const QMap<QString, QString> &metadata, const QPoint &tracks, Render *render, NotesPlugin *notes, bool *openBackup, MainWindow *parent = nullptr);
|
||||
~KdenliveDoc();
|
||||
QDomNodeList producersList();
|
||||
double fps() const;
|
||||
@@ -229,7 +229,7 @@ public slots:
|
||||
* Emits docModified conected to MainWindow::slotUpdateDocumentState \n
|
||||
* @param mod (optional) true if the document has to be saved */
|
||||
void setModified(bool mod = true);
|
||||
void slotProxyCurrentItem(bool doProxy, QList<ProjectClip *> clipList = QList<ProjectClip *>(), bool force = false, QUndoCommand *masterCommand = Q_NULLPTR);
|
||||
void slotProxyCurrentItem(bool doProxy, QList<ProjectClip *> clipList = QList<ProjectClip *>(), bool force = false, QUndoCommand *masterCommand = nullptr);
|
||||
/** @brief Saves the current project at the autosave location.
|
||||
* @description The autosave files are in ~/.kde/data/stalefiles/kdenlive/ */
|
||||
void slotAutoSave();
|
||||
|
||||
@@ -48,6 +48,16 @@ QPixmap KThumb::getImage(const QUrl &url, int frame, int width, int height)
|
||||
return pix;
|
||||
}
|
||||
Mlt::Producer *producer = new Mlt::Producer(profile, url.toLocalFile().toUtf8().constData());
|
||||
if (KdenliveSettings::gpu_accel()) {
|
||||
QString service = producer->get("mlt_service");
|
||||
QString res = producer->get("resource");
|
||||
delete producer;
|
||||
producer = new Mlt::Producer(profile, service.toUtf8().constData(), res.toUtf8().constData());
|
||||
Mlt::Filter scaler(profile, "swscale");
|
||||
Mlt::Filter converter(profile, "avcolor_space");
|
||||
producer->attach(scaler);
|
||||
producer->attach(converter);
|
||||
}
|
||||
pix = QPixmap::fromImage(getFrame(producer, frame, width, height));
|
||||
delete producer;
|
||||
return pix;
|
||||
@@ -75,17 +85,16 @@ QImage KThumb::getFrame(Mlt::Producer *producer, int framepos, int displayWidth,
|
||||
}
|
||||
|
||||
//static
|
||||
QImage KThumb::getFrame(Mlt::Frame *frame, int width, int height)
|
||||
QImage KThumb::getFrame(Mlt::Frame *frame, int width, int height, bool forceRescale)
|
||||
{
|
||||
if (frame == nullptr || !frame->is_valid()) {
|
||||
QImage p(width, height, QImage::Format_ARGB32_Premultiplied);
|
||||
p.fill(QColor(Qt::red).rgb());
|
||||
return p;
|
||||
}
|
||||
int ow = width;
|
||||
int oh = height;
|
||||
int ow = forceRescale ? 0 : width;
|
||||
int oh = forceRescale ? 0 : height;
|
||||
mlt_image_format format = mlt_image_rgb24a;
|
||||
//frame->set("progressive", "1");
|
||||
ow += ow % 2;
|
||||
const uchar *imagedata = frame->get_image(format, ow, oh);
|
||||
if (imagedata) {
|
||||
@@ -113,7 +122,7 @@ uint KThumb::imageVariance(const QImage &image)
|
||||
{
|
||||
uint delta = 0;
|
||||
uint avg = 0;
|
||||
uint bytes = image.byteCount();
|
||||
uint bytes = static_cast<uint>(image.byteCount());
|
||||
uint STEPS = bytes / 2;
|
||||
QVarLengthArray<uchar> pivot(STEPS);
|
||||
const uchar *bits = image.bits();
|
||||
|
||||
@@ -38,11 +38,11 @@ namespace KThumb
|
||||
QPixmap getImage(const QUrl &url, int width, int height = -1);
|
||||
QPixmap getImage(const QUrl &url, int frame, int width, int height = -1);
|
||||
QImage getFrame(Mlt::Producer *producer, int framepos, int displayWidth, int height);
|
||||
QImage getFrame(Mlt::Frame *frame, int width, int height);
|
||||
QImage getFrame(Mlt::Frame *frame, int width, int height, bool forceRescale = false);
|
||||
/** @brief Calculates image variance, useful to know if a thumbnail is interesting.
|
||||
* @return an integer between 0 and 100. 0 means no variance, eg. black image while bigger values mean contrasted image
|
||||
* */
|
||||
uint imageVariance(const QImage &image);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -82,7 +82,7 @@ DvdWizard::DvdWizard(MonitorManager *manager, const QString &url, QWidget *paren
|
||||
m_status.error_box->setHidden(true);
|
||||
m_status.tmp_folder->setUrl(QUrl::fromLocalFile(KdenliveSettings::currenttmpfolder()));
|
||||
m_status.tmp_folder->setMode(KFile::Directory | KFile::ExistingOnly);
|
||||
m_status.iso_image->setUrl(QUrl::fromLocalFile(QDir::homePath() + "/untitled.iso"));
|
||||
m_status.iso_image->setUrl(QUrl::fromLocalFile(QDir::homePath() + QStringLiteral("/untitled.iso")));
|
||||
m_status.iso_image->setFilter(QStringLiteral("*.iso"));
|
||||
m_status.iso_image->setMode(KFile::File);
|
||||
|
||||
@@ -181,13 +181,13 @@ void DvdWizard::slotPageChanged(int page)
|
||||
void DvdWizard::generateDvd()
|
||||
{
|
||||
m_isoMessage->animatedHide();
|
||||
QDir dir(m_status.tmp_folder->url().toLocalFile() + "DVD/");
|
||||
QDir dir(m_status.tmp_folder->url().toLocalFile() + QStringLiteral("DVD/"));
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(dir.absolutePath());
|
||||
}
|
||||
if (!dir.exists()) {
|
||||
// We failed creating tmp DVD directory
|
||||
KMessageBox::sorry(this, i18n("Cannot create temporary directory %1", m_status.tmp_folder->url().toLocalFile() + "DVD"));
|
||||
KMessageBox::sorry(this, i18n("Cannot create temporary directory %1", m_status.tmp_folder->url().toLocalFile() + QStringLiteral("DVD")));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -247,7 +247,7 @@ void DvdWizard::generateDvd()
|
||||
m_pageMenu->createBackgroundImage(m_menuImageBackground.fileName(), false);
|
||||
images->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok")));
|
||||
connect(&m_menuJob, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(slotProcessMenuStatus(int, QProcess::ExitStatus)));
|
||||
////qCDebug(KDENLIVE_LOG) << "/// STARTING MLT VOB CREATION: "<<m_selectedImage.fileName()<<m_menuImageBackground.fileName();
|
||||
//qCDebug(KDENLIVE_LOG) << "/// STARTING MLT VOB CREATION: "<<m_selectedImage.fileName()<<m_menuImageBackground.fileName();
|
||||
if (!m_pageMenu->menuMovie()) {
|
||||
// create menu vob file
|
||||
m_vobitem = m_status.job_progress->item(1);
|
||||
@@ -284,7 +284,7 @@ void DvdWizard::generateDvd()
|
||||
args << QStringLiteral("-transition") << QStringLiteral("composite") << QStringLiteral("always_active=1");
|
||||
args << QStringLiteral("-consumer") << "avformat:" + m_menuFinalVideo.fileName() << QStringLiteral("properties=DVD");
|
||||
m_menuJob.start(KdenliveSettings::rendererpath(), args);
|
||||
////qCDebug(KDENLIVE_LOG)<<"// STARTING MENU JOB, image: "<<m_menuImageBackground.fileName()<<"\n-------------";
|
||||
//qCDebug(KDENLIVE_LOG)<<"// STARTING MENU JOB, image: "<<m_menuImageBackground.fileName()<<"\n-------------";
|
||||
}
|
||||
} else {
|
||||
processDvdauthor();
|
||||
@@ -354,17 +354,17 @@ void DvdWizard::processSpumux()
|
||||
++i;
|
||||
}
|
||||
|
||||
QFile data(m_menuFile.fileName());
|
||||
if (data.open(QFile::WriteOnly)) {
|
||||
data.write(doc.toString().toUtf8());
|
||||
QFile menuFile(m_menuFile.fileName());
|
||||
if (menuFile.open(QFile::WriteOnly)) {
|
||||
menuFile.write(doc.toString().toUtf8());
|
||||
}
|
||||
data.close();
|
||||
menuFile.close();
|
||||
|
||||
////qCDebug(KDENLIVE_LOG) << " SPUMUX DATA: " << doc.toString();
|
||||
//qCDebug(KDENLIVE_LOG) << " SPUMUX DATA: " << doc.toString();
|
||||
|
||||
QStringList args;
|
||||
args << QStringLiteral("-s") << QStringLiteral("0") << m_menuFile.fileName();
|
||||
////qCDebug(KDENLIVE_LOG) << "SPM ARGS: " << args << m_menuVideo.fileName() << m_menuVobFile.fileName();
|
||||
//qCDebug(KDENLIVE_LOG) << "SPM ARGS: " << args << m_menuVideo.fileName() << m_menuVobFile.fileName();
|
||||
|
||||
QProcess spumux;
|
||||
QString menuMovieUrl;
|
||||
@@ -398,7 +398,7 @@ void DvdWizard::processSpumux()
|
||||
//qCDebug(KDENLIVE_LOG) << "/// RENDERING SPUMUX MENU timed out";
|
||||
errorMessage(i18n("Rendering job timed out"));
|
||||
spuitem->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close")));
|
||||
m_status.error_log->append("<a name=\"result\" /><br /><strong>" + i18n("Menu job timed out"));
|
||||
m_status.error_log->append(QStringLiteral("<a name=\"result\" /><br /><strong>") + i18n("Menu job timed out"));
|
||||
m_status.error_log->scrollToAnchor(QStringLiteral("result"));
|
||||
m_status.error_box->setHidden(false);
|
||||
m_status.menu_file->setPlainText(m_menuFile.readAll());
|
||||
@@ -461,16 +461,16 @@ void DvdWizard::processSpumux()
|
||||
|
||||
////qCDebug(KDENLIVE_LOG) << " SPUMUX DATA: " << doc.toString();
|
||||
|
||||
if (data.open(QFile::WriteOnly)) {
|
||||
data.write(docLetter.toString().toUtf8());
|
||||
if (menuFile.open(QFile::WriteOnly)) {
|
||||
menuFile.write(docLetter.toString().toUtf8());
|
||||
}
|
||||
data.close();
|
||||
menuFile.close();
|
||||
spumux.setStandardInputFile(m_menuVobFile.fileName());
|
||||
spumux.setStandardOutputFile(m_letterboxMovie.fileName());
|
||||
args.clear();
|
||||
args << QStringLiteral("-s") << QStringLiteral("1") << m_menuFile.fileName();
|
||||
spumux.start(QStringLiteral("spumux"), args);
|
||||
////qCDebug(KDENLIVE_LOG) << "SPM ARGS LETTERBOX: " << args << m_menuVideo.fileName() << m_letterboxMovie.fileName();
|
||||
//qCDebug(KDENLIVE_LOG) << "SPM ARGS LETTERBOX: " << args << m_menuVideo.fileName() << m_letterboxMovie.fileName();
|
||||
if (spumux.waitForFinished()) {
|
||||
m_status.error_log->append(spumux.readAllStandardError());
|
||||
if (spumux.exitStatus() == QProcess::CrashExit) {
|
||||
@@ -489,7 +489,7 @@ void DvdWizard::processSpumux()
|
||||
//qCDebug(KDENLIVE_LOG) << "/// RENDERING SPUMUX MENU timed out";
|
||||
errorMessage(i18n("Rendering job timed out"));
|
||||
spuitem->setIcon(QIcon::fromTheme(QStringLiteral("dialog-close")));
|
||||
m_status.error_log->append("<a name=\"result\" /><br /><strong>" + i18n("Menu job timed out"));
|
||||
m_status.error_log->append(QStringLiteral("<a name=\"result\" /><br /><strong>") + i18n("Menu job timed out"));
|
||||
m_status.error_log->scrollToAnchor(QStringLiteral("result"));
|
||||
m_status.error_box->setHidden(false);
|
||||
m_status.menu_file->setPlainText(m_menuFile.readAll());
|
||||
@@ -515,7 +515,7 @@ void DvdWizard::processDvdauthor(const QString &menuMovieUrl, const QMap<QString
|
||||
authitem->setIcon(QIcon::fromTheme(QStringLiteral("system-run")));
|
||||
QDomDocument dvddoc;
|
||||
QDomElement auth = dvddoc.createElement(QStringLiteral("dvdauthor"));
|
||||
auth.setAttribute(QStringLiteral("dest"), m_status.tmp_folder->url().toLocalFile() + "DVD");
|
||||
auth.setAttribute(QStringLiteral("dest"), m_status.tmp_folder->url().toLocalFile() + QStringLiteral("DVD"));
|
||||
dvddoc.appendChild(auth);
|
||||
QDomElement vmgm = dvddoc.createElement(QStringLiteral("vmgm"));
|
||||
auth.appendChild(vmgm);
|
||||
@@ -593,7 +593,7 @@ void DvdWizard::processDvdauthor(const QString &menuMovieUrl, const QMap<QString
|
||||
for (int i = 0; i < buttons.count(); ++i) {
|
||||
QDomElement button = dvddoc.createElement(QStringLiteral("button"));
|
||||
button.setAttribute(QStringLiteral("name"), 'b' + QString::number(i));
|
||||
nametext = dvddoc.createTextNode('{' + buttonsTarget.at(i) + ";}");
|
||||
nametext = dvddoc.createTextNode(QLatin1Char('{') + buttonsTarget.at(i) + QStringLiteral(";}"));
|
||||
button.appendChild(nametext);
|
||||
pgc.appendChild(button);
|
||||
}
|
||||
@@ -657,7 +657,7 @@ void DvdWizard::processDvdauthor(const QString &menuMovieUrl, const QMap<QString
|
||||
if (i == voburls.count() - 1) {
|
||||
call = dvddoc.createTextNode(QStringLiteral("{g1 = 0; call menu;}"));
|
||||
} else {
|
||||
call = dvddoc.createTextNode("{if ( g1 eq 999 ) { call menu; } jump title " + QString::number(i + 2).rightJustified(2, '0') + ";}");
|
||||
call = dvddoc.createTextNode("{if ( g1 eq 999 ) { call menu; } jump title " + QString::number(i + 2).rightJustified(2, '0') + QStringLiteral(";}"));
|
||||
}
|
||||
post.appendChild(call);
|
||||
pgc2.appendChild(post);
|
||||
@@ -745,7 +745,7 @@ void DvdWizard::slotRenderFinished(int exitCode, QProcess::ExitStatus status)
|
||||
if (status == QProcess::CrashExit || exitCode != 0) {
|
||||
errorMessage(i18n("DVDAuthor process crashed"));
|
||||
QString result(m_dvdauthor->readAllStandardError());
|
||||
result.append("<a name=\"result\" /><br /><strong>");
|
||||
result.append(QStringLiteral("<a name=\"result\" /><br /><strong>"));
|
||||
result.append(i18n("DVDAuthor process crashed.</strong><br />"));
|
||||
m_status.error_log->append(result);
|
||||
m_status.error_log->scrollToAnchor(QStringLiteral("result"));
|
||||
@@ -769,9 +769,9 @@ void DvdWizard::slotRenderFinished(int exitCode, QProcess::ExitStatus status)
|
||||
m_dvdauthor = nullptr;
|
||||
|
||||
// Check if DVD structure has the necessary info
|
||||
if (!QFile::exists(m_status.tmp_folder->url().toLocalFile() + "/DVD/VIDEO_TS/VIDEO_TS.IFO")) {
|
||||
if (!QFile::exists(m_status.tmp_folder->url().toLocalFile() + QStringLiteral("/DVD/VIDEO_TS/VIDEO_TS.IFO"))) {
|
||||
errorMessage(i18n("DVD structure broken"));
|
||||
m_status.error_log->append(m_creationLog + "<a name=\"result\" /><br /><strong>" + i18n("DVD structure broken"));
|
||||
m_status.error_log->append(m_creationLog + QStringLiteral("<a name=\"result\" /><br /><strong>") + i18n("DVD structure broken"));
|
||||
m_status.error_log->scrollToAnchor(QStringLiteral("result"));
|
||||
m_status.error_box->setHidden(false);
|
||||
m_status.menu_file->setPlainText(m_menuFile.readAll());
|
||||
@@ -786,7 +786,7 @@ void DvdWizard::slotRenderFinished(int exitCode, QProcess::ExitStatus status)
|
||||
}
|
||||
authitem->setIcon(QIcon::fromTheme(QStringLiteral("dialog-ok")));
|
||||
QStringList args;
|
||||
args << QStringLiteral("-dvd-video") << QStringLiteral("-v") << QStringLiteral("-o") << m_status.iso_image->url().toLocalFile() << m_status.tmp_folder->url().toLocalFile() + QDir::separator() + "DVD";
|
||||
args << QStringLiteral("-dvd-video") << QStringLiteral("-v") << QStringLiteral("-o") << m_status.iso_image->url().toLocalFile() << m_status.tmp_folder->url().toLocalFile() + QDir::separator() + QStringLiteral("DVD");
|
||||
|
||||
if (m_mkiso) {
|
||||
m_mkiso->blockSignals(true);
|
||||
@@ -823,7 +823,7 @@ void DvdWizard::slotIsoFinished(int exitCode, QProcess::ExitStatus status)
|
||||
if (status == QProcess::CrashExit || exitCode != 0) {
|
||||
errorMessage(i18n("ISO creation process crashed."));
|
||||
QString result(m_mkiso->readAllStandardError());
|
||||
result.append("<a name=\"result\" /><br /><strong>");
|
||||
result.append(QStringLiteral("<a name=\"result\" /><br /><strong>"));
|
||||
result.append(i18n("ISO creation process crashed."));
|
||||
m_status.error_log->append(result);
|
||||
m_status.error_log->scrollToAnchor(QStringLiteral("result"));
|
||||
@@ -854,7 +854,7 @@ void DvdWizard::slotIsoFinished(int exitCode, QProcess::ExitStatus status)
|
||||
iso.remove();
|
||||
}
|
||||
errorMessage(i18n("DVD ISO is broken"));
|
||||
m_status.error_log->append(m_creationLog + "<br /><a name=\"result\" /><strong>" + i18n("DVD ISO is broken") + "</strong>");
|
||||
m_status.error_log->append(m_creationLog + QStringLiteral("<br /><a name=\"result\" /><strong>") + i18n("DVD ISO is broken") + QStringLiteral("</strong>"));
|
||||
m_status.error_log->scrollToAnchor(QStringLiteral("result"));
|
||||
m_status.error_box->setHidden(false);
|
||||
m_status.menu_file->setPlainText(m_menuFile.readAll());
|
||||
@@ -870,7 +870,9 @@ void DvdWizard::slotIsoFinished(int exitCode, QProcess::ExitStatus status)
|
||||
//qCDebug(KDENLIVE_LOG) << m_creationLog;
|
||||
infoMessage(i18n("DVD ISO image %1 successfully created.", m_status.iso_image->url().toLocalFile()));
|
||||
|
||||
m_status.error_log->append("<a name=\"result\" /><strong>" + i18n("DVD ISO image %1 successfully created.", m_status.iso_image->url().toLocalFile()) + "</strong>");
|
||||
m_status.error_log->append(QStringLiteral("<a name=\"result\" /><strong>")
|
||||
+ i18n("DVD ISO image %1 successfully created.", m_status.iso_image->url().toLocalFile())
|
||||
+ QStringLiteral("</strong>"));
|
||||
m_status.error_log->scrollToAnchor(QStringLiteral("result"));
|
||||
m_status.button_preview->setEnabled(true);
|
||||
m_status.button_burn->setEnabled(true);
|
||||
@@ -881,7 +883,7 @@ void DvdWizard::slotIsoFinished(int exitCode, QProcess::ExitStatus status)
|
||||
|
||||
void DvdWizard::cleanup()
|
||||
{
|
||||
QDir dir(m_status.tmp_folder->url().toLocalFile() + QDir::separator() + "DVD");
|
||||
QDir dir(m_status.tmp_folder->url().toLocalFile() + QDir::separator() + QStringLiteral("DVD"));
|
||||
// Try to make sure we delete the correct directory
|
||||
if (dir.exists() && dir.dirName() == QLatin1String("DVD")) {
|
||||
dir.removeRecursively();
|
||||
@@ -890,10 +892,9 @@ void DvdWizard::cleanup()
|
||||
|
||||
void DvdWizard::slotPreview()
|
||||
{
|
||||
QStringList programNames;
|
||||
programNames << QStringLiteral("xine") << QStringLiteral("vlc");
|
||||
const QStringList programNames = { QStringLiteral("xine"), QStringLiteral("vlc")};
|
||||
QString exec;
|
||||
foreach (const QString &prog, programNames) {
|
||||
for (const QString &prog : programNames) {
|
||||
exec = QStandardPaths::findExecutable(prog);
|
||||
if (!exec.isEmpty()) {
|
||||
break;
|
||||
@@ -929,8 +930,8 @@ void DvdWizard::slotGenerate()
|
||||
m_status.job_progress->item(i)->setIcon(QIcon());
|
||||
}
|
||||
QString warnMessage;
|
||||
if (QFile::exists(m_status.tmp_folder->url().toLocalFile() + "DVD")) {
|
||||
warnMessage.append(i18n("Folder %1 already exists. Overwrite?\n", m_status.tmp_folder->url().toLocalFile() + "DVD"));
|
||||
if (QFile::exists(m_status.tmp_folder->url().toLocalFile() + QStringLiteral("DVD"))) {
|
||||
warnMessage.append(i18n("Folder %1 already exists. Overwrite?\n", m_status.tmp_folder->url().toLocalFile() + QStringLiteral("DVD")));
|
||||
}
|
||||
if (QFile::exists(m_status.iso_image->url().toLocalFile())) {
|
||||
warnMessage.append(i18n("Image file %1 already exists. Overwrite?", m_status.iso_image->url().toLocalFile()));
|
||||
@@ -1026,18 +1027,18 @@ void DvdWizard::slotLoad()
|
||||
QString profile = dvdproject.attribute(QStringLiteral("profile"));
|
||||
m_pageVob->setProfile(profile);
|
||||
m_pageVob->clear();
|
||||
m_status.tmp_folder->setUrl(QUrl(dvdproject.attribute(QStringLiteral("tmp_folder"))));
|
||||
m_status.iso_image->setUrl(QUrl(dvdproject.attribute(QStringLiteral("iso_image"))));
|
||||
m_status.tmp_folder->setUrl(QUrl::fromLocalFile(dvdproject.attribute(QStringLiteral("tmp_folder"))));
|
||||
m_status.iso_image->setUrl(QUrl::fromLocalFile(dvdproject.attribute(QStringLiteral("iso_image"))));
|
||||
QString intro = dvdproject.attribute(QStringLiteral("intro_movie"));
|
||||
if (!intro.isEmpty()) {
|
||||
m_pageVob->slotAddVobFile(QUrl(intro));
|
||||
m_pageVob->slotAddVobFile(QUrl::fromLocalFile(intro));
|
||||
m_pageVob->setUseIntroMovie(true);
|
||||
}
|
||||
|
||||
QDomNodeList vobs = doc.elementsByTagName(QStringLiteral("vob"));
|
||||
for (int i = 0; i < vobs.count(); ++i) {
|
||||
QDomElement e = vobs.at(i).toElement();
|
||||
m_pageVob->slotAddVobFile(QUrl(e.attribute(QStringLiteral("file"))), e.attribute(QStringLiteral("chapters")));
|
||||
m_pageVob->slotAddVobFile(QUrl::fromLocalFile(e.attribute(QStringLiteral("file"))), e.attribute(QStringLiteral("chapters")));
|
||||
}
|
||||
m_pageMenu->loadXml(m_pageVob->dvdFormat(), dvdproject.firstChildElement(QStringLiteral("menu")));
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ class DvdWizard : public QWizard
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DvdWizard(MonitorManager *manager, const QString &url = QString(), QWidget *parent = Q_NULLPTR);
|
||||
explicit DvdWizard(MonitorManager *manager, const QString &url = QString(), QWidget *parent = nullptr);
|
||||
virtual ~DvdWizard();
|
||||
void processSpumux();
|
||||
|
||||
|
||||
@@ -114,9 +114,10 @@ void DvdWizardChapters::slotAddChapter()
|
||||
|
||||
void DvdWizardChapters::updateMonitorMarkers()
|
||||
{
|
||||
QStringList chapters = m_view.vob_list->itemData(m_view.vob_list->currentIndex(), Qt::UserRole + 1).toStringList();
|
||||
const QStringList chapters = m_view.vob_list->itemData(m_view.vob_list->currentIndex(), Qt::UserRole + 1).toStringList();
|
||||
QList<CommentedTime> markers;
|
||||
foreach (const QString &frame, chapters) {
|
||||
markers.reserve(chapters.count());
|
||||
for (const QString &frame : chapters) {
|
||||
markers << CommentedTime(GenTime(frame.toInt(), m_tc.fps()), QString());
|
||||
}
|
||||
m_monitor->setMarkers(markers);
|
||||
@@ -176,7 +177,7 @@ void DvdWizardChapters::setVobFiles(DVDFORMAT format, const QStringList &movies,
|
||||
m_view.vob_list->clear();
|
||||
for (int i = 0; i < movies.count(); ++i) {
|
||||
m_view.vob_list->addItem(movies.at(i), durations.at(i));
|
||||
m_view.vob_list->setItemData(i, chapters.at(i).split(';'), Qt::UserRole + 1);
|
||||
m_view.vob_list->setItemData(i, chapters.at(i).split(QLatin1Char(';')), Qt::UserRole + 1);
|
||||
}
|
||||
m_view.vob_list->blockSignals(false);
|
||||
if (m_view.chapters_box->checkState() == Qt::Checked) {
|
||||
@@ -228,13 +229,13 @@ QStringList DvdWizardChapters::selectedTargets() const
|
||||
int max = m_view.vob_list->count();
|
||||
for (int i = 0; i < max; ++i) {
|
||||
// rightJustified: fill with 0s to make menus with more than 9 buttons work (now up to 99 buttons possible)
|
||||
result.append("jump title " + QString::number(i + 1).rightJustified(2, '0'));
|
||||
result.append(QStringLiteral("jump title ") + QString::number(i + 1).rightJustified(2, '0'));
|
||||
if (!m_view.chapters_box->isChecked()) {
|
||||
continue;
|
||||
}
|
||||
QStringList chapters = m_view.vob_list->itemData(i, Qt::UserRole + 1).toStringList();
|
||||
for (int j = 0; j < chapters.count(); ++j) {
|
||||
result.append("jump title " + QString::number(i + 1).rightJustified(2, '0') + " chapter " + QString::number(j + 1).rightJustified(2, '0'));
|
||||
result.append(QStringLiteral("jump title ") + QString::number(i + 1).rightJustified(2, '0') + QStringLiteral(" chapter ") + QString::number(j + 1).rightJustified(2, '0'));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -32,7 +32,7 @@ class DvdWizardChapters : public QWizardPage
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DvdWizardChapters(MonitorManager *manager, DVDFORMAT format, QWidget *parent = Q_NULLPTR);
|
||||
explicit DvdWizardChapters(MonitorManager *manager, DVDFORMAT format, QWidget *parent = nullptr);
|
||||
virtual ~DvdWizardChapters();
|
||||
void changeProfile(DVDFORMAT format);
|
||||
void setPal(bool isPal);
|
||||
|
||||
@@ -44,19 +44,23 @@ void DvdScene::setProfile(int width, int height)
|
||||
m_height = height;
|
||||
setSceneRect(0, 0, m_width, m_height);
|
||||
}
|
||||
|
||||
int DvdScene::gridSize() const
|
||||
{
|
||||
return m_gridSize;
|
||||
}
|
||||
|
||||
void DvdScene::setGridSize(int gridSize)
|
||||
{
|
||||
m_gridSize = gridSize;
|
||||
}
|
||||
|
||||
void DvdScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
|
||||
{
|
||||
QGraphicsScene::mouseReleaseEvent(mouseEvent);
|
||||
emit sceneChanged();
|
||||
}
|
||||
|
||||
void DvdScene::drawForeground(QPainter *painter, const QRectF &rect)
|
||||
{
|
||||
// draw the grid if needed
|
||||
@@ -716,7 +720,12 @@ void DvdWizardMenu::createBackgroundImage(const QString &img1, bool letterbox)
|
||||
QPainter p(&img);
|
||||
p.setRenderHints(QPainter::Antialiasing, true);
|
||||
p.setRenderHints(QPainter::TextAntialiasing, true);
|
||||
// set image grid to "1" to ensure we don't display dots all over
|
||||
// the image when rendering
|
||||
int oldSize = m_scene->gridSize();
|
||||
m_scene->setGridSize(1);
|
||||
m_scene->render(&p, QRectF(0, 0, img.width(), img.height()));
|
||||
m_scene->setGridSize(oldSize);
|
||||
//m_scene->render(&p, target, source, Qt::IgnoreAspectRatio);
|
||||
p.end();
|
||||
img.save(img1);
|
||||
@@ -778,7 +787,7 @@ QMap<QString, QRect> DvdWizardMenu::buttonsInfo(bool letterbox)
|
||||
}
|
||||
QString command = button->command();
|
||||
if (button->backMenu()) {
|
||||
command.prepend("g1 = 999;");
|
||||
command.prepend(QStringLiteral("g1 = 999;"));
|
||||
}
|
||||
info.insertMulti(command, adjustedRect);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ class DvdScene : public QGraphicsScene
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DvdScene(QObject *parent = Q_NULLPTR);
|
||||
explicit DvdScene(QObject *parent = nullptr);
|
||||
void setProfile(int width, int height);
|
||||
int gridSize() const;
|
||||
void setGridSize(int gridSize);
|
||||
@@ -55,7 +55,7 @@ class DvdButtonUnderline : public QGraphicsRectItem
|
||||
{
|
||||
|
||||
public:
|
||||
explicit DvdButtonUnderline(const QRectF &rect, QGraphicsItem *parent = Q_NULLPTR) : QGraphicsRectItem(rect, parent) {}
|
||||
explicit DvdButtonUnderline(const QRectF &rect, QGraphicsItem *parent = nullptr) : QGraphicsRectItem(rect, parent) {}
|
||||
|
||||
int type() const Q_DECL_OVERRIDE
|
||||
{
|
||||
@@ -87,7 +87,7 @@ class DvdWizardMenu : public QWizardPage
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DvdWizardMenu(DVDFORMAT format, QWidget *parent = Q_NULLPTR);
|
||||
explicit DvdWizardMenu(DVDFORMAT format, QWidget *parent = nullptr);
|
||||
virtual ~DvdWizardMenu();
|
||||
bool createMenu() const;
|
||||
void createBackgroundImage(const QString &img1, bool letterbox);
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <KRecentDirs>
|
||||
#include <KMessageBox>
|
||||
|
||||
#include <QAction>
|
||||
#include <QFileDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QDomDocument>
|
||||
@@ -176,8 +177,8 @@ void DvdWizardVob::slotShowTranscodeInfo()
|
||||
QString log = QString(m_transcodeProcess.readAll());
|
||||
if (m_duration == 0) {
|
||||
if (log.contains(QStringLiteral("Duration:"))) {
|
||||
QString data = log.section(QStringLiteral("Duration:"), 1, 1).section(',', 0, 0).simplified();
|
||||
QStringList numbers = data.split(':');
|
||||
QString durationstr = log.section(QStringLiteral("Duration:"), 1, 1).section(QLatin1Char(','), 0, 0).simplified();
|
||||
const QStringList numbers = durationstr.split(QLatin1Char(':'));
|
||||
if (numbers.size() < 3) {
|
||||
return;
|
||||
}
|
||||
@@ -190,9 +191,9 @@ void DvdWizardVob::slotShowTranscodeInfo()
|
||||
}
|
||||
} else if (log.contains(QStringLiteral("time="))) {
|
||||
int progress;
|
||||
QString time = log.section(QStringLiteral("time="), 1, 1).simplified().section(' ', 0, 0);
|
||||
QString time = log.section(QStringLiteral("time="), 1, 1).simplified().section(QLatin1Char(' '), 0, 0);
|
||||
if (time.contains(QLatin1Char(':'))) {
|
||||
QStringList numbers = time.split(':');
|
||||
const QStringList numbers = time.split(QLatin1Char(':'));
|
||||
if (numbers.size() < 3) {
|
||||
return;
|
||||
}
|
||||
@@ -219,7 +220,7 @@ void DvdWizardVob::slotAbortTranscode()
|
||||
void DvdWizardVob::slotTranscodeFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
|
||||
slotTranscodedClip(m_currentTranscoding.filename, m_currentTranscoding.filename + m_currentTranscoding.params.section(QStringLiteral("%1"), 1, 1).section(' ', 0, 0));
|
||||
slotTranscodedClip(m_currentTranscoding.filename, m_currentTranscoding.filename + m_currentTranscoding.params.section(QStringLiteral("%1"), 1, 1).section(QLatin1Char(' '), 0, 0));
|
||||
if (!m_transcodeQueue.isEmpty()) {
|
||||
m_transcodeProcess.close();
|
||||
processTranscoding();
|
||||
@@ -264,7 +265,7 @@ void DvdWizardVob::slotAddVobList(QList<QUrl> list)
|
||||
{
|
||||
if (list.isEmpty()) {
|
||||
QString allExtensions = ClipCreationDialog::getExtensions().join(QLatin1Char(' '));
|
||||
QString dialogFilter = i18n("All Supported Files") + " (" + allExtensions + ");; " + i18n("MPEG Files") + " (*.mpeg *.mpg *.vob);; " + i18n("All Files") + " (*.*)";
|
||||
QString dialogFilter = i18n("All Supported Files") + QStringLiteral(" (") + allExtensions + QStringLiteral(");; ") + i18n("MPEG Files") + QStringLiteral(" (*.mpeg *.mpg *.vob);; ") + i18n("All Files") + QStringLiteral(" (*.*)");
|
||||
list = QFileDialog::getOpenFileUrls(this, i18n("Add new video file"), QUrl::fromLocalFile(KRecentDirs::dir(QStringLiteral(":KdenliveDvdFolder"))), dialogFilter);
|
||||
if (!list.isEmpty()) {
|
||||
KRecentDirs::add(QStringLiteral(":KdenliveDvdFolder"), list.at(0).adjusted(QUrl::RemoveFilename).toLocalFile());
|
||||
@@ -287,13 +288,13 @@ void DvdWizardVob::slotAddVobFile(const QUrl &url, const QString &chapters, bool
|
||||
|
||||
Mlt::Profile profile;
|
||||
profile.set_explicit(false);
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(m_vobList, QStringList() << url.toLocalFile() << QString() << KIO::convertSize(fileSize));
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(m_vobList, QStringList() << url.toLocalFile() << QString() << KIO::convertSize(static_cast<KIO::filesize_t>(fileSize)));
|
||||
item->setData(2, Qt::UserRole, fileSize);
|
||||
item->setData(0, Qt::DecorationRole, QIcon::fromTheme(QStringLiteral("video-x-generic")).pixmap(60, 45));
|
||||
item->setToolTip(0, url.toLocalFile());
|
||||
|
||||
QString resource = url.toLocalFile();
|
||||
resource.prepend("avformat:");
|
||||
resource.prepend(QStringLiteral("avformat:"));
|
||||
Mlt::Producer *producer = new Mlt::Producer(profile, resource.toUtf8().data());
|
||||
if (producer && producer->is_valid() && !producer->is_blank()) {
|
||||
double fps = profile.fps();
|
||||
@@ -363,15 +364,13 @@ void DvdWizardVob::slotAddVobFile(const QUrl &url, const QString &chapters, bool
|
||||
// Cannot load movie, reject
|
||||
showError(i18n("The clip %1 is invalid.", url.fileName()));
|
||||
}
|
||||
if (producer) {
|
||||
delete producer;
|
||||
}
|
||||
delete producer;
|
||||
|
||||
if (chapters.isEmpty() == false) {
|
||||
item->setData(1, Qt::UserRole + 1, chapters);
|
||||
} else if (QFile::exists(url.toLocalFile() + ".dvdchapter")) {
|
||||
} else if (QFile::exists(url.toLocalFile() + QStringLiteral(".dvdchapter"))) {
|
||||
// insert chapters as children
|
||||
QFile file(url.toLocalFile() + ".dvdchapter");
|
||||
QFile file(url.toLocalFile() + QStringLiteral(".dvdchapter"));
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
QDomDocument doc;
|
||||
if (doc.setContent(&file) == false) {
|
||||
@@ -379,10 +378,10 @@ void DvdWizardVob::slotAddVobFile(const QUrl &url, const QString &chapters, bool
|
||||
return;
|
||||
}
|
||||
file.close();
|
||||
QDomNodeList chapters = doc.elementsByTagName(QStringLiteral("chapter"));
|
||||
QDomNodeList chapterNodes = doc.elementsByTagName(QStringLiteral("chapter"));
|
||||
QStringList chaptersList;
|
||||
for (int j = 0; j < chapters.count(); ++j) {
|
||||
chaptersList.append(QString::number(chapters.at(j).toElement().attribute(QStringLiteral("time")).toInt()));
|
||||
for (int j = 0; j < chapterNodes.count(); ++j) {
|
||||
chaptersList.append(QString::number(chapterNodes.at(j).toElement().attribute(QStringLiteral("time")).toInt()));
|
||||
}
|
||||
item->setData(1, Qt::UserRole + 1, chaptersList.join(QLatin1Char(';')));
|
||||
}
|
||||
@@ -536,8 +535,8 @@ void DvdWizardVob::slotCheckVobList()
|
||||
}
|
||||
|
||||
qint64 maxSize = (qint64) 47000 * 100000;
|
||||
m_capacityBar->setValue(100 * totalSize / maxSize);
|
||||
m_capacityBar->setText(KIO::convertSize(totalSize));
|
||||
m_capacityBar->setValue(static_cast<int>(100 * totalSize / maxSize));
|
||||
m_capacityBar->setText(KIO::convertSize(static_cast<KIO::filesize_t>(totalSize)));
|
||||
}
|
||||
|
||||
void DvdWizardVob::slotItemUp()
|
||||
@@ -695,7 +694,7 @@ void DvdWizardVob::slotTranscodeFiles()
|
||||
}
|
||||
TranscodeJobInfo jobInfo;
|
||||
jobInfo.filename = item->text(0);
|
||||
jobInfo.params = params.section(';', 0, 0);
|
||||
jobInfo.params = params.section(QLatin1Char(';'), 0, 0);
|
||||
jobInfo.postParams = postParams;
|
||||
m_transcodeQueue << jobInfo;
|
||||
}
|
||||
@@ -712,7 +711,7 @@ void DvdWizardVob::processTranscoding()
|
||||
QStringList parameters;
|
||||
QStringList postParams = m_currentTranscoding.postParams;
|
||||
QString params = m_currentTranscoding.params;
|
||||
QString extension = params.section(QStringLiteral("%1"), 1, 1).section(' ', 0, 0);
|
||||
QString extension = params.section(QStringLiteral("%1"), 1, 1).section(QLatin1Char(' '), 0, 0);
|
||||
parameters << QStringLiteral("-i") << m_currentTranscoding.filename;
|
||||
if (QFile::exists(m_currentTranscoding.filename + extension)) {
|
||||
if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", m_currentTranscoding.filename + extension)) == KMessageBox::No) {
|
||||
@@ -724,7 +723,7 @@ void DvdWizardVob::processTranscoding()
|
||||
}
|
||||
|
||||
bool replaceVfParams = false;
|
||||
QStringList splitted = params.split(' ');
|
||||
const QStringList splitted = params.split(QLatin1Char(' '));
|
||||
foreach (QString s, splitted) {
|
||||
if (replaceVfParams) {
|
||||
parameters << postParams.at(1);
|
||||
@@ -762,13 +761,13 @@ void DvdWizardVob::slotTranscodedClip(const QString &src, const QString &transco
|
||||
|
||||
Mlt::Profile profile;
|
||||
profile.set_explicit(false);
|
||||
item->setText(2, KIO::convertSize(fileSize));
|
||||
item->setText(2, KIO::convertSize(static_cast<KIO::filesize_t>(fileSize)));
|
||||
item->setData(2, Qt::UserRole, fileSize);
|
||||
item->setData(0, Qt::DecorationRole, QIcon::fromTheme(QStringLiteral("video-x-generic")).pixmap(60, 45));
|
||||
item->setToolTip(0, transcoded);
|
||||
|
||||
QString resource = transcoded;
|
||||
resource.prepend("avformat:");
|
||||
resource.prepend(QStringLiteral("avformat:"));
|
||||
Mlt::Producer *producer = new Mlt::Producer(profile, resource.toUtf8().data());
|
||||
if (producer && producer->is_valid() && !producer->is_blank()) {
|
||||
double fps = profile.fps();
|
||||
|
||||
@@ -106,7 +106,7 @@ class DvdWizardVob : public QWizardPage
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DvdWizardVob(QWidget *parent = Q_NULLPTR);
|
||||
explicit DvdWizardVob(QWidget *parent = nullptr);
|
||||
virtual ~DvdWizardVob();
|
||||
QStringList selectedUrls() const;
|
||||
void setUrl(const QString &url);
|
||||
|
||||
@@ -47,19 +47,17 @@ void EffectBasket::slotReloadBasket()
|
||||
|
||||
QMimeData *EffectBasket::mimeData(const QList<QListWidgetItem *> list) const
|
||||
{
|
||||
QDomDocument doc;
|
||||
if (list.isEmpty()) {
|
||||
return new QMimeData;
|
||||
}
|
||||
QDomDocument doc;
|
||||
QListWidgetItem *item = list.at(0);
|
||||
int type = item->data(EffectsListWidget::TypeRole).toInt();
|
||||
QStringList info = item->data(EffectsListWidget::IdRole).toStringList();
|
||||
QDomElement effect = EffectsListWidget::itemEffect(type, info);
|
||||
doc.appendChild(doc.importNode(effect, true));
|
||||
QMimeData *mime = new QMimeData;
|
||||
QByteArray data;
|
||||
data.append(doc.toString().toUtf8());
|
||||
mime->setData(QStringLiteral("kdenlive/effectslist"), data);
|
||||
mime->setData(QStringLiteral("kdenlive/effectslist"), doc.toString().toUtf8());
|
||||
return mime;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ QDomElement EffectsList::getEffectByName(const QString &name) const
|
||||
}
|
||||
if (name == effectName) {
|
||||
QDomNodeList params = effect.elementsByTagName(QStringLiteral("parameter"));
|
||||
for (int i = 0; i < params.count(); ++i) {
|
||||
QDomElement e = params.item(i).toElement();
|
||||
for (int j = 0; j < params.count(); ++j) {
|
||||
QDomElement e = params.item(j).toElement();
|
||||
if (!e.hasAttribute(QStringLiteral("value")) && e.attribute(QStringLiteral("type")) != QLatin1String("animatedrect") && e.attribute(QStringLiteral("paramlist")) != QLatin1String("%lumaPaths")) {
|
||||
e.setAttribute(QStringLiteral("value"), e.attribute(QStringLiteral("default")));
|
||||
}
|
||||
@@ -192,7 +192,7 @@ QString EffectsList::getEffectInfo(const QDomElement &effect) const
|
||||
|
||||
namenode = effect.firstChildElement(QStringLiteral("author"));
|
||||
if (!namenode.isNull() && !namenode.text().isEmpty()) {
|
||||
info.append("<br /><strong>" + i18n("Author:") + " </strong>" + i18n(namenode.text().toUtf8().data()));
|
||||
info.append(QStringLiteral("<br /><strong>") + i18n("Author:") + QStringLiteral(" </strong>") + i18n(namenode.text().toUtf8().data()));
|
||||
}
|
||||
|
||||
namenode = effect.firstChildElement(QStringLiteral("version"));
|
||||
|
||||
@@ -55,8 +55,8 @@ bool MyTreeWidgetSearchLine::itemMatches(const QTreeWidgetItem *item, const QStr
|
||||
return true;
|
||||
}
|
||||
QString itemText = item->text(0);
|
||||
itemText = itemText.normalized(QString::NormalizationForm_D).remove(QRegExp("[^a-zA-Z0-9\\s]"));
|
||||
QString patt = pattern.normalized(QString::NormalizationForm_D).remove(QRegExp("[^a-zA-Z0-9\\s]"));
|
||||
itemText = itemText.normalized(QString::NormalizationForm_D).remove(QRegExp(QStringLiteral("[^a-zA-Z0-9\\s]")));
|
||||
QString patt = pattern.normalized(QString::NormalizationForm_D).remove(QRegExp(QStringLiteral("[^a-zA-Z0-9\\s]")));
|
||||
for (int i = 0; i < item->treeWidget()->columnCount(); i++) {
|
||||
if (item->treeWidget()->columnWidth(i) > 0 && itemText.indexOf(patt, 0, Qt::CaseInsensitive) >= 0) {
|
||||
return true;
|
||||
@@ -231,10 +231,10 @@ void EffectsListView::creatFavoriteBasket(QListWidget *list)
|
||||
}
|
||||
for (int j = 0; j < folder->childCount(); ++j) {
|
||||
QTreeWidgetItem *item = folder->child(j);
|
||||
QStringList data = item->data(0, Qt::UserRole + 1).toStringList();
|
||||
QString id = data.at(1);
|
||||
QStringList effectdata = item->data(0, Qt::UserRole + 1).toStringList();
|
||||
QString id = effectdata.at(1);
|
||||
if (id.isEmpty()) {
|
||||
id = data.at(0);
|
||||
id = effectdata.at(0);
|
||||
}
|
||||
if (KdenliveSettings::favorite_effects().contains(id)) {
|
||||
QListWidgetItem *it = new QListWidgetItem(item->icon(0), item->text(0));
|
||||
@@ -285,10 +285,10 @@ void EffectsListView::filterList()
|
||||
QTreeWidgetItem *folder = m_effectsList->topLevelItem(i);
|
||||
for (int j = 0; j < folder->childCount(); ++j) {
|
||||
QTreeWidgetItem *item = folder->child(j);
|
||||
QStringList data = item->data(0, Qt::UserRole + 1).toStringList();
|
||||
QString id = data.at(1);
|
||||
QStringList effectdata = item->data(0, Qt::UserRole + 1).toStringList();
|
||||
QString id = effectdata.at(1);
|
||||
if (id.isEmpty()) {
|
||||
id = data.at(0);
|
||||
id = effectdata.at(0);
|
||||
}
|
||||
if (KdenliveSettings::favorite_effects().contains(id)) {
|
||||
favorites << item->clone();
|
||||
@@ -445,14 +445,14 @@ void EffectsListView::slotRemoveEffect()
|
||||
|
||||
QTreeWidgetItem *item = m_effectsList->currentItem();
|
||||
QString effectId = item->text(0);
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/effects/";
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/effects/");
|
||||
|
||||
QDir directory = QDir(path);
|
||||
QStringList filter;
|
||||
filter << QStringLiteral("*.xml");
|
||||
const QStringList fileList = directory.entryList(filter, QDir::Files);
|
||||
QString itemName;
|
||||
foreach (const QString &filename, fileList) {
|
||||
for (const QString &filename : fileList) {
|
||||
itemName = directory.absoluteFilePath(filename);
|
||||
QDomDocument doc;
|
||||
QFile file(itemName);
|
||||
|
||||
@@ -40,7 +40,7 @@ class TreeEventEater : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TreeEventEater(QObject *parent = Q_NULLPTR);
|
||||
explicit TreeEventEater(QObject *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
|
||||
@@ -53,7 +53,7 @@ class MyTreeWidgetSearchLine : public KTreeWidgetSearchLine
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MyTreeWidgetSearchLine(QWidget *parent = Q_NULLPTR);
|
||||
explicit MyTreeWidgetSearchLine(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
bool itemMatches(const QTreeWidgetItem *item, const QString &pattern) const Q_DECL_OVERRIDE;
|
||||
@@ -70,7 +70,7 @@ class MyDropButton : public QToolButton
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit MyDropButton(QWidget *parent = Q_NULLPTR) : QToolButton(parent)
|
||||
explicit MyDropButton(QWidget *parent = nullptr) : QToolButton(parent)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
setAutoExclusive(true);
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
TransitionMode = 1
|
||||
};
|
||||
|
||||
explicit EffectsListView(LISTMODE mode = EffectMode, QWidget *parent = Q_NULLPTR);
|
||||
explicit EffectsListView(LISTMODE mode = EffectMode, QWidget *parent = nullptr);
|
||||
|
||||
/** @brief Re-initializes the list of effects. */
|
||||
void reloadEffectList(QMenu *effectsMenu, KActionCategory *effectActions);
|
||||
|
||||
@@ -170,12 +170,12 @@ void EffectsListWidget::initList(QMenu *effectsMenu, KActionCategory *effectActi
|
||||
if (topLevelItem(i)->data(0, TypeRole) == EffectsList::TRANSITION_TYPE) {
|
||||
QTreeWidgetItem *item = topLevelItem(i);
|
||||
QAction *a = new QAction(item->icon(0), item->text(0), effectsMenu);
|
||||
QStringList data = item->data(0, IdRole).toStringList();
|
||||
QString id = data.at(1);
|
||||
QStringList effectdata = item->data(0, IdRole).toStringList();
|
||||
QString id = effectdata.at(1);
|
||||
if (id.isEmpty()) {
|
||||
id = data.at(0);
|
||||
id = effectdata.at(0);
|
||||
}
|
||||
a->setData(data);
|
||||
a->setData(effectdata);
|
||||
a->setIconVisibleInMenu(false);
|
||||
effectsMenu->addAction(a);
|
||||
effectActions->addAction("transition_" + id, a);
|
||||
@@ -203,12 +203,12 @@ void EffectsListWidget::initList(QMenu *effectsMenu, KActionCategory *effectActi
|
||||
for (int j = 0; j < effectsInCategory; ++j) {
|
||||
QTreeWidgetItem *item = topLevelItem(i)->child(j);
|
||||
QAction *a = new QAction(item->icon(0), item->text(0), sub);
|
||||
QStringList data = item->data(0, IdRole).toStringList();
|
||||
QString id = data.at(1);
|
||||
QStringList effectdata = item->data(0, IdRole).toStringList();
|
||||
QString id = effectdata.at(1);
|
||||
if (id.isEmpty()) {
|
||||
id = data.at(0);
|
||||
id = effectdata.at(0);
|
||||
}
|
||||
a->setData(data);
|
||||
a->setData(effectdata);
|
||||
a->setIconVisibleInMenu(false);
|
||||
if (hasSubCategories) {
|
||||
// put action in sub category
|
||||
@@ -439,7 +439,7 @@ QMimeData *EffectsListWidget::mimeData(const QList<QTreeWidgetItem *> list) cons
|
||||
{
|
||||
QDomDocument doc;
|
||||
bool transitionMode = false;
|
||||
foreach (QTreeWidgetItem *item, list) {
|
||||
for (QTreeWidgetItem *item : list) {
|
||||
if (item->flags() & Qt::ItemIsDragEnabled) {
|
||||
int type = item->data(0, TypeRole).toInt();
|
||||
if (type == EffectsList::TRANSITION_TYPE) {
|
||||
@@ -453,9 +453,7 @@ QMimeData *EffectsListWidget::mimeData(const QList<QTreeWidgetItem *> list) cons
|
||||
}
|
||||
}
|
||||
QMimeData *mime = new QMimeData;
|
||||
QByteArray data;
|
||||
data.append(doc.toString().toUtf8());
|
||||
mime->setData(transitionMode ? "kdenlive/transitionslist" : "kdenlive/effectslist", data);
|
||||
mime->setData(transitionMode ? "kdenlive/transitionslist" : "kdenlive/effectslist", doc.toString().toUtf8());
|
||||
return mime;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ public:
|
||||
static const int TypeRole = Qt::UserRole;
|
||||
static const int IdRole = TypeRole + 1;
|
||||
|
||||
explicit EffectsListWidget(QWidget *parent = Q_NULLPTR);
|
||||
explicit EffectsListWidget(QWidget *parent = nullptr);
|
||||
virtual ~EffectsListWidget();
|
||||
const QDomElement currentEffect() const;
|
||||
QString currentInfo() const;
|
||||
|
||||
@@ -44,7 +44,7 @@ void initEffects::refreshLumas()
|
||||
MainWindow::m_lumaFiles.clear();
|
||||
fileFilters << QStringLiteral("*.png") << QStringLiteral("*.pgm");
|
||||
QStringList customLumas = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, QStringLiteral("lumas"), QStandardPaths::LocateDirectory);
|
||||
customLumas.append(QString(mlt_environment("MLT_DATA")) + "/lumas");
|
||||
customLumas.append(QString(mlt_environment("MLT_DATA")) + QStringLiteral("/lumas"));
|
||||
foreach (const QString &folder, customLumas) {
|
||||
QDir topDir(folder);
|
||||
QStringList folders = topDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
|
||||
@@ -128,7 +128,7 @@ QDomDocument initEffects::getUsedCustomEffects(const QMap<QString, QString> &eff
|
||||
}
|
||||
|
||||
//static
|
||||
bool initEffects::parseEffectFiles(Mlt::Repository *repository, const QString &locale)
|
||||
bool initEffects::parseEffectFiles(std::unique_ptr<Mlt::Repository> &repository, const QString &locale)
|
||||
{
|
||||
bool movit = false;
|
||||
QStringList::Iterator more;
|
||||
@@ -394,7 +394,7 @@ void initEffects::parseCustomEffectsFile()
|
||||
* cannot be sure about it.
|
||||
*/
|
||||
QMap<QString, QDomElement> effectsMap;
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/effects";
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/effects");
|
||||
QDir directory = QDir(path);
|
||||
QStringList filter;
|
||||
filter << QStringLiteral("*.xml");
|
||||
@@ -434,7 +434,7 @@ void initEffects::parseCustomEffectsFile()
|
||||
}
|
||||
|
||||
// static
|
||||
void initEffects::parseEffectFile(EffectsList *customEffectList, EffectsList *audioEffectList, EffectsList *videoEffectList, const QString &name, const QStringList &filtersList, const QStringList &producersList, Mlt::Repository *repository, const QMap<QString, QString> &effectDescriptions)
|
||||
void initEffects::parseEffectFile(EffectsList *customEffectList, EffectsList *audioEffectList, EffectsList *videoEffectList, const QString &name, const QStringList &filtersList, const QStringList &producersList, std::unique_ptr<Mlt::Repository> &repository, const QMap<QString, QString> &effectDescriptions)
|
||||
{
|
||||
QDomDocument doc;
|
||||
QFile file(name);
|
||||
@@ -550,7 +550,7 @@ void initEffects::parseEffectFile(EffectsList *customEffectList, EffectsList *au
|
||||
}
|
||||
}
|
||||
|
||||
QDomDocument initEffects::createDescriptionFromMlt(Mlt::Repository *repository, const QString & /*type*/, const QString &filtername)
|
||||
QDomDocument initEffects::createDescriptionFromMlt(std::unique_ptr<Mlt::Repository> &repository, const QString & /*type*/, const QString &filtername)
|
||||
{
|
||||
|
||||
QDomDocument ret;
|
||||
@@ -664,9 +664,9 @@ QDomDocument initEffects::createDescriptionFromMlt(Mlt::Repository *repository,
|
||||
}
|
||||
|
||||
if (paramdesc.get("description")) {
|
||||
QDomElement desc = ret.createElement(QStringLiteral("comment"));
|
||||
desc.appendChild(ret.createTextNode(paramdesc.get("description")));
|
||||
params.appendChild(desc);
|
||||
QDomElement comment = ret.createElement(QStringLiteral("comment"));
|
||||
comment.appendChild(ret.createTextNode(paramdesc.get("description")));
|
||||
params.appendChild(comment);
|
||||
}
|
||||
|
||||
eff.appendChild(params);
|
||||
@@ -683,7 +683,7 @@ QDomDocument initEffects::createDescriptionFromMlt(Mlt::Repository *repository,
|
||||
return ret;
|
||||
}
|
||||
|
||||
void initEffects::fillTransitionsList(Mlt::Repository *repository, EffectsList *transitions, QStringList names)
|
||||
void initEffects::fillTransitionsList(std::unique_ptr<Mlt::Repository> &repository, EffectsList *transitions, QStringList names)
|
||||
{
|
||||
// Remove transitions that are not implemented.
|
||||
int pos = names.indexOf(QStringLiteral("mix"));
|
||||
@@ -786,7 +786,9 @@ void initEffects::fillTransitionsList(Mlt::Repository *repository, EffectsList *
|
||||
desc.appendChild(ret.createTextNode(i18n("A key-framable alpha-channel compositor for two frames.")));
|
||||
paramList.append(quickParameterFill(ret, i18n("Geometry"), QStringLiteral("geometry"), QStringLiteral("geometry"), QStringLiteral("0%/0%:100%x100%:100"), QStringLiteral("-500;-500;-500;-500;0"), QStringLiteral("500;500;500;500;100")));
|
||||
paramList.append(quickParameterFill(ret, i18n("Alpha Channel Operation"), QStringLiteral("operator"), QStringLiteral("list"), QStringLiteral("over"), QString(), QString(), QStringLiteral("over,and,or,xor"), i18n("Over,And,Or,Xor")));
|
||||
paramList.append(quickParameterFill(ret, i18n("Align"), QStringLiteral("aligned"), QStringLiteral("bool"), QStringLiteral("0"), QStringLiteral("0"), QStringLiteral("1")));
|
||||
paramList.append(quickParameterFill(ret, i18n("Align"), QStringLiteral("aligned"), QStringLiteral("bool"), QStringLiteral("1"), QStringLiteral("0"), QStringLiteral("1")));
|
||||
paramList.append(quickParameterFill(ret, i18n("Align"), QStringLiteral("valign"), QStringLiteral("fixed"), QStringLiteral("middle"), QStringLiteral("middle"), QStringLiteral("middle")));
|
||||
paramList.append(quickParameterFill(ret, i18n("Align"), QStringLiteral("halign"), QStringLiteral("fixed"), QStringLiteral("centre"), QStringLiteral("centre"), QStringLiteral("centre")));
|
||||
paramList.append(quickParameterFill(ret, i18n("Fill"), QStringLiteral("fill"), QStringLiteral("bool"), QStringLiteral("1"), QStringLiteral("0"), QStringLiteral("1")));
|
||||
paramList.append(quickParameterFill(ret, i18n("Distort"), QStringLiteral("distort"), QStringLiteral("bool"), QStringLiteral("0"), QStringLiteral("0"), QStringLiteral("1")));
|
||||
paramList.append(quickParameterFill(ret, i18n("Wipe Method"), QStringLiteral("luma"), QStringLiteral("list"), QString(), QString(), QString(), QStringLiteral("%lumaPaths"), QString()));
|
||||
@@ -852,16 +854,26 @@ void initEffects::fillTransitionsList(Mlt::Repository *repository, EffectsList *
|
||||
}
|
||||
|
||||
// Add some virtual transitions.
|
||||
QString slidetrans = "<ktransition tag=\"composite\" id=\"slide\"><name>" + i18n("Slide") + "</name><description>" + i18n("Slide image from one side to another.") + "</description><parameter tag=\"geometry\" type=\"wipe\" default=\"-100%,0%:100%x100%;-1=0%,0%:100%x100%\" name=\"geometry\"><name>" + i18n("Direction") + "</name> </parameter><parameter tag=\"aligned\" default=\"0\" type=\"bool\" name=\"aligned\" ><name>" + i18n("Align") + "</name></parameter><parameter tag=\"progressive\" default=\"1\" type=\"bool\" name=\"progressive\" ><name>" + i18n("Force Progressive Rendering") + "</name></parameter><parameter tag=\"deinterlace\" default=\"0\" type=\"bool\" name=\"deinterlace\" ><name>" + i18n("Force Deinterlace Overlay") + "</name></parameter><parameter tag=\"invert\" default=\"0\" type=\"bool\" name=\"invert\" ><name>" + i18nc("@property: means that the image is inverted", "Invert") + "</name></parameter></ktransition>";
|
||||
QString slidetrans = QStringLiteral("<ktransition tag=\"composite\" id=\"slide\"><name>") + i18n("Slide") +
|
||||
QStringLiteral("</name><description>") + i18n("Slide image from one side to another.")
|
||||
+ QStringLiteral("</description><parameter tag=\"geometry\" type=\"wipe\" default=\"-100%,0%:100%x100%;-1=0%,0%:100%x100%\" name=\"geometry\"><name>")
|
||||
+ i18n("Direction") + QStringLiteral("</name> </parameter><parameter tag=\"aligned\" default=\"0\" type=\"bool\" name=\"aligned\" ><name>")
|
||||
+ i18n("Align") + QStringLiteral("</name></parameter><parameter tag=\"progressive\" default=\"1\" type=\"bool\" name=\"progressive\" ><name>")
|
||||
+ i18n("Force Progressive Rendering") + QStringLiteral("</name></parameter><parameter tag=\"deinterlace\" default=\"0\" type=\"bool\" name=\"deinterlace\" ><name>")
|
||||
+ i18n("Force Deinterlace Overlay") + QStringLiteral("</name></parameter><parameter tag=\"invert\" default=\"0\" type=\"bool\" name=\"invert\" ><name>")
|
||||
+ i18nc("@property: means that the image is inverted", "Invert") + QStringLiteral("</name></parameter></ktransition>");
|
||||
QDomDocument ret;
|
||||
ret.setContent(slidetrans);
|
||||
transitions->append(ret.documentElement());
|
||||
|
||||
QString dissolve = "<ktransition tag=\"luma\" id=\"dissolve\"><name>" + i18n("Dissolve") + "</name><description>" + i18n("Fade out one video while fading in the other video.") + "</description><parameter tag=\"reverse\" default=\"0\" type=\"bool\" name=\"reverse\" ><name>" + i18n("Reverse") + "</name></parameter></ktransition>";
|
||||
QString dissolve = QStringLiteral("<ktransition tag=\"luma\" id=\"dissolve\"><name>")
|
||||
+ i18n("Dissolve") + QStringLiteral("</name><description>") + i18n("Fade out one video while fading in the other video.")
|
||||
+ QStringLiteral("</description><parameter tag=\"reverse\" default=\"0\" type=\"bool\" name=\"reverse\" ><name>")
|
||||
+ i18n("Reverse") + QStringLiteral("</name></parameter></ktransition>");
|
||||
ret.setContent(dissolve);
|
||||
transitions->append(ret.documentElement());
|
||||
|
||||
/*QString alphatrans = "<ktransition tag=\"composite\" id=\"alphatransparency\" ><name>" + i18n("Alpha Transparency") + "</name><description>" + i18n("Make alpha channel transparent.") + "</description><parameter tag=\"geometry\" type=\"fixed\" default=\"0%,0%:100%x100%\" name=\"geometry\"><name>" + i18n("Direction") + "</name></parameter><parameter tag=\"fill\" default=\"0\" type=\"bool\" name=\"fill\" ><name>" + i18n("Rescale") + "</name></parameter><parameter tag=\"aligned\" default=\"0\" type=\"bool\" name=\"aligned\" ><name>" + i18n("Align") + "</name></parameter></ktransition>";
|
||||
/*QString alphatrans = "<ktransition tag=\"composite\" id=\"alphatransparency\" ><name>" + i18n("Alpha Transparency") + QStringLiteral("</name><description>") + i18n("Make alpha channel transparent.") + "</description><parameter tag=\"geometry\" type=\"fixed\" default=\"0%,0%:100%x100%\" name=\"geometry\"><name>" + i18n("Direction") + "</name></parameter><parameter tag=\"fill\" default=\"0\" type=\"bool\" name=\"fill\" ><name>" + i18n("Rescale") + "</name></parameter><parameter tag=\"aligned\" default=\"0\" type=\"bool\" name=\"aligned\" ><name>" + i18n("Align") + "</name></parameter></ktransition>";
|
||||
ret.setContent(alphatrans);
|
||||
transitions->append(ret.documentElement());*/
|
||||
}
|
||||
@@ -896,13 +908,13 @@ QDomElement initEffects::quickParameterFill(QDomDocument &doc, const QString &na
|
||||
}
|
||||
|
||||
// static
|
||||
void initEffects::parseTransitionFile(EffectsList *transitionList, const QString &name, Mlt::Repository *repository, const QStringList &installedTransitions, const QMap<QString, QString> &effectDescriptions)
|
||||
void initEffects::parseTransitionFile(EffectsList *transitionList, const QString &name, std::unique_ptr<Mlt::Repository> &repository, const QStringList &installedTransitions, const QMap<QString, QString> &effectDescriptions)
|
||||
{
|
||||
QDomDocument doc;
|
||||
QFile file(name);
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
return;
|
||||
}
|
||||
QDomDocument doc;
|
||||
QTextStream out(&file);
|
||||
QString fileContent = out.readAll();
|
||||
file.close();
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <QDomDocument>
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
#include <memory>
|
||||
#include <mlt++/Mlt.h>
|
||||
|
||||
/**Init the MLT effects
|
||||
@@ -41,9 +42,9 @@ public:
|
||||
* It checks for all available effects and transitions, removes blacklisted
|
||||
* ones, calls fillTransitionsList() and parseEffectFile() to fill the lists
|
||||
* (with sorted, unique items) and then fills the global lists. */
|
||||
static bool parseEffectFiles(Mlt::Repository *repository, const QString &locale = QString());
|
||||
static bool parseEffectFiles(std::unique_ptr<Mlt::Repository> &repository, const QString &locale = QString());
|
||||
static void refreshLumas();
|
||||
static QDomDocument createDescriptionFromMlt(Mlt::Repository *repository, const QString &type, const QString &name);
|
||||
static QDomDocument createDescriptionFromMlt(std::unique_ptr<Mlt::Repository> &repository, const QString &type, const QString &name);
|
||||
static QDomDocument getUsedCustomEffects(const QMap<QString, QString> &effectids);
|
||||
|
||||
/** @brief Fills the transitions list.
|
||||
@@ -54,7 +55,7 @@ public:
|
||||
* It creates an element for each transition, asking to MLT for information
|
||||
* when possible, using default parameters otherwise. It also adds some
|
||||
* "virtual" transition, and removes those not implemented. */
|
||||
static void fillTransitionsList(Mlt::Repository *repository, EffectsList *transitions, QStringList names);
|
||||
static void fillTransitionsList(std::unique_ptr<Mlt::Repository> &repository, EffectsList *transitions, QStringList names);
|
||||
|
||||
/** @brief Creates an element describing a transition parameter.
|
||||
* @param doc document containing the transition element
|
||||
@@ -87,8 +88,8 @@ public:
|
||||
EffectsList *videoEffectList,
|
||||
const QString &name, const QStringList &filtersList,
|
||||
const QStringList &producersList,
|
||||
Mlt::Repository *repository, const QMap<QString, QString> &effectDescriptions);
|
||||
static void parseTransitionFile(EffectsList *transitionList, const QString &name, Mlt::Repository *repository, const QStringList &installedTransitions, const QMap<QString, QString> &effectDescriptions);
|
||||
std::unique_ptr<Mlt::Repository> &repository, const QMap<QString, QString> &effectDescriptions);
|
||||
static void parseTransitionFile(EffectsList *transitionList, const QString &name, std::unique_ptr<Mlt::Repository> &repository, const QStringList &installedTransitions, const QMap<QString, QString> &effectDescriptions);
|
||||
|
||||
/** @brief Reloads information about custom effects. */
|
||||
static void parseCustomEffectsFile();
|
||||
|
||||
@@ -30,7 +30,7 @@ class AbstractCollapsibleWidget : public QWidget, public Ui::CollapsibleWidget_U
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AbstractCollapsibleWidget(QWidget *parent = Q_NULLPTR);
|
||||
explicit AbstractCollapsibleWidget(QWidget *parent = nullptr);
|
||||
virtual void setActive(bool activate) = 0;
|
||||
virtual bool isGroup() const = 0;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ class AnimKeyframeRuler : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AnimKeyframeRuler(int min, int max, QWidget *parent = Q_NULLPTR);
|
||||
explicit AnimKeyframeRuler(int min, int max, QWidget *parent = nullptr);
|
||||
int position() const;
|
||||
int frameLength;
|
||||
void updateKeyframes(const QVector<int> &keyframes, const QVector<int> &types, int attachToEnd);
|
||||
|
||||
@@ -213,7 +213,7 @@ void CollapsibleEffect::slotCreateGroup()
|
||||
void CollapsibleEffect::slotCreateRegion()
|
||||
{
|
||||
QString allExtensions = ClipCreationDialog::getExtensions().join(QLatin1Char(' '));
|
||||
const QString dialogFilter = allExtensions + ' ' + QLatin1Char('|') + i18n("All Supported Files") + "\n* " + QLatin1Char('|') + i18n("All Files");
|
||||
const QString dialogFilter = allExtensions + QLatin1Char(' ') + QLatin1Char('|') + i18n("All Supported Files") + QStringLiteral("\n* ") + QLatin1Char('|') + i18n("All Files");
|
||||
QString clipFolder = KRecentDirs::dir(QStringLiteral(":KdenliveClipFolder"));
|
||||
if (clipFolder.isEmpty()) {
|
||||
clipFolder = QDir::homePath();
|
||||
@@ -221,8 +221,8 @@ void CollapsibleEffect::slotCreateRegion()
|
||||
QPointer<QFileDialog> d = new QFileDialog(QApplication::activeWindow(), QString(), clipFolder, dialogFilter);
|
||||
d->setFileMode(QFileDialog::ExistingFile);
|
||||
if (d->exec() == QDialog::Accepted && !d->selectedUrls().isEmpty()) {
|
||||
KRecentDirs::add(QStringLiteral(":KdenliveClipFolder"), d->selectedUrls().first().adjusted(QUrl::RemoveFilename).toLocalFile());
|
||||
emit createRegion(effectIndex(), d->selectedUrls().first());
|
||||
KRecentDirs::add(QStringLiteral(":KdenliveClipFolder"), d->selectedUrls().constFirst().adjusted(QUrl::RemoveFilename).toLocalFile());
|
||||
emit createRegion(effectIndex(), d->selectedUrls().constFirst());
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
@@ -371,17 +371,17 @@ void CollapsibleEffect::slotEffectDown()
|
||||
void CollapsibleEffect::slotSaveEffect()
|
||||
{
|
||||
QString name = QInputDialog::getText(this, i18n("Save Effect"), i18n("Name for saved effect: "));
|
||||
if (name.isEmpty()) {
|
||||
if (name.trimmed().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/effects/");
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/effects/"));
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(QStringLiteral("."));
|
||||
}
|
||||
|
||||
if (dir.exists(name + ".xml")) if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", name + ".xml")) == KMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
if (dir.exists(name + QStringLiteral(".xml"))) if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", name + QStringLiteral(".xml"))) == KMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
|
||||
QDomDocument doc;
|
||||
QDomElement effect = m_effect.cloneNode().toElement();
|
||||
@@ -404,7 +404,7 @@ void CollapsibleEffect::slotSaveEffect()
|
||||
effectprops.setAttribute(QStringLiteral("id"), name);
|
||||
effectprops.setAttribute(QStringLiteral("type"), QStringLiteral("custom"));
|
||||
|
||||
QFile file(dir.absoluteFilePath(name + ".xml"));
|
||||
QFile file(dir.absoluteFilePath(name + QStringLiteral(".xml")));
|
||||
if (file.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||
QTextStream out(&file);
|
||||
out << doc.toString();
|
||||
@@ -450,7 +450,7 @@ void CollapsibleEffect::updateCollapsedState()
|
||||
QString info = m_info.toString();
|
||||
if (info != m_effect.attribute(QStringLiteral("kdenlive_info"))) {
|
||||
m_effect.setAttribute(QStringLiteral("kdenlive_info"), info);
|
||||
emit parameterChanged(m_original_effect, m_effect, effectIndex());
|
||||
emit parameterChanged(m_original_effect, m_effect, effectIndex(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,10 +516,10 @@ void CollapsibleEffect::updateFrameInfo()
|
||||
}
|
||||
}
|
||||
|
||||
void CollapsibleEffect::setActiveKeyframe(int frame)
|
||||
void CollapsibleEffect::setActiveKeyframe(int kf)
|
||||
{
|
||||
if (m_paramWidget) {
|
||||
m_paramWidget->setActiveKeyframe(frame);
|
||||
m_paramWidget->setActiveKeyframe(kf);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,18 +634,18 @@ void CollapsibleEffect::dragLeaveEvent(QDragLeaveEvent */*event*/)
|
||||
frame->setStyleSheet(frame->styleSheet());
|
||||
}
|
||||
|
||||
void CollapsibleEffect::importKeyframes(const QString &keyframes)
|
||||
void CollapsibleEffect::importKeyframes(const QString &kf)
|
||||
{
|
||||
QMap<QString, QString> data;
|
||||
if (keyframes.contains(QLatin1Char('\n'))) {
|
||||
const QStringList params = keyframes.split(QLatin1Char('\n'), QString::SkipEmptyParts);
|
||||
QMap<QString, QString> keyframes;
|
||||
if (kf.contains(QLatin1Char('\n'))) {
|
||||
const QStringList params = kf.split(QLatin1Char('\n'), QString::SkipEmptyParts);
|
||||
for (const QString ¶m : params) {
|
||||
data.insert(param.section(QLatin1Char('='), 0, 0), param.section(QLatin1Char('='), 1));
|
||||
keyframes.insert(param.section(QLatin1Char('='), 0, 0), param.section(QLatin1Char('='), 1));
|
||||
}
|
||||
} else {
|
||||
data.insert(keyframes.section(QLatin1Char('='), 0, 0), keyframes.section(QLatin1Char('='), 1));
|
||||
keyframes.insert(kf.section(QLatin1Char('='), 0, 0), kf.section(QLatin1Char('='), 1));
|
||||
}
|
||||
emit importClipKeyframes(AVWidget, m_itemInfo, m_effect.cloneNode().toElement(), data);
|
||||
emit importClipKeyframes(AVWidget, m_itemInfo, m_effect.cloneNode().toElement(), keyframes);
|
||||
}
|
||||
|
||||
void CollapsibleEffect::dropEvent(QDropEvent *event)
|
||||
@@ -740,9 +740,9 @@ void CollapsibleEffect::setRange(int inPoint, int outPoint)
|
||||
m_paramWidget->setRange(inPoint, outPoint);
|
||||
}
|
||||
|
||||
void CollapsibleEffect::setKeyframes(const QString &tag, const QString &data)
|
||||
void CollapsibleEffect::setKeyframes(const QString &tag, const QString &keyframes)
|
||||
{
|
||||
m_paramWidget->setKeyframes(tag, data);
|
||||
m_paramWidget->setKeyframes(tag, keyframes);
|
||||
}
|
||||
|
||||
bool CollapsibleEffect::isMovable() const
|
||||
|
||||
@@ -42,7 +42,7 @@ class CollapsibleEffect : public AbstractCollapsibleWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CollapsibleEffect(const QDomElement &effect, const QDomElement &original_effect, const ItemInfo &info, EffectMetaInfo *metaInfo, bool canMoveUp, bool lastEffect, QWidget *parent = Q_NULLPTR);
|
||||
explicit CollapsibleEffect(const QDomElement &effect, const QDomElement &original_effect, const ItemInfo &info, EffectMetaInfo *metaInfo, bool canMoveUp, bool lastEffect, QWidget *parent = nullptr);
|
||||
~CollapsibleEffect();
|
||||
QLabel *title;
|
||||
|
||||
@@ -78,11 +78,11 @@ public:
|
||||
/** @brief Set clip in / out points. */
|
||||
void setRange(int inPoint, int outPoint);
|
||||
/** @brief Import keyframes from a clip's data. */
|
||||
void setKeyframes(const QString &tag, const QString &data);
|
||||
void setKeyframes(const QString &tag, const QString &keyframes);
|
||||
/** @brief Pass frame size info (dar, etc). */
|
||||
void updateFrameInfo();
|
||||
/** @brief Select active keyframe. */
|
||||
void setActiveKeyframe(int frame);
|
||||
void setActiveKeyframe(int kf);
|
||||
/** @brief Returns true if effect can be moved (false for speed effect). */
|
||||
bool isMovable() const;
|
||||
|
||||
@@ -141,7 +141,7 @@ protected:
|
||||
void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
signals:
|
||||
void parameterChanged(const QDomElement &, const QDomElement &, int);
|
||||
void parameterChanged(const QDomElement &, const QDomElement &, int, bool update = true);
|
||||
void syncEffectsPos(int);
|
||||
void effectStateChanged(bool, int ix, MonitorSceneType effectNeedsMonitorScene);
|
||||
void deleteEffect(const QDomElement &);
|
||||
@@ -157,7 +157,7 @@ signals:
|
||||
void unGroup(CollapsibleEffect *);
|
||||
void createRegion(int, const QUrl &);
|
||||
void deleteGroup(const QDomDocument &);
|
||||
void importClipKeyframes(GraphicsRectItem, ItemInfo, QDomElement, const QMap<QString, QString> &data = QMap<QString, QString>());
|
||||
void importClipKeyframes(GraphicsRectItem, ItemInfo, QDomElement, const QMap<QString, QString> &keyframes = QMap<QString, QString>());
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -157,6 +157,7 @@ void CollapsibleGroup::slotDeleteGroup()
|
||||
void CollapsibleGroup::slotEffectUp()
|
||||
{
|
||||
QList<int> indexes;
|
||||
indexes.reserve(m_subWidgets.count());
|
||||
for (int i = 0; i < m_subWidgets.count(); ++i) {
|
||||
indexes << m_subWidgets.at(i)->effectIndex();
|
||||
}
|
||||
@@ -166,6 +167,7 @@ void CollapsibleGroup::slotEffectUp()
|
||||
void CollapsibleGroup::slotEffectDown()
|
||||
{
|
||||
QList<int> indexes;
|
||||
indexes.reserve(m_subWidgets.count());
|
||||
for (int i = 0; i < m_subWidgets.count(); ++i) {
|
||||
indexes << m_subWidgets.at(i)->effectIndex();
|
||||
}
|
||||
@@ -178,14 +180,16 @@ void CollapsibleGroup::slotSaveGroup()
|
||||
if (name.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/effects/");
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QStringLiteral("/effects/"));
|
||||
if (!dir.exists()) {
|
||||
dir.mkpath(QStringLiteral("."));
|
||||
}
|
||||
|
||||
if (dir.exists(name + ".xml")) if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", name + ".xml")) == KMessageBox::No) {
|
||||
if (dir.exists(name + QStringLiteral(".xml"))) {
|
||||
if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", name + QStringLiteral(".xml"))) == KMessageBox::No) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QDomDocument doc = effectsData();
|
||||
QDomElement base = doc.documentElement();
|
||||
@@ -207,7 +211,7 @@ void CollapsibleGroup::slotSaveGroup()
|
||||
base.setAttribute(QStringLiteral("id"), name);
|
||||
base.setAttribute(QStringLiteral("type"), QStringLiteral("custom"));
|
||||
|
||||
QFile file(dir.absoluteFilePath(name + ".xml"));
|
||||
QFile file(dir.absoluteFilePath(name + QStringLiteral(".xml")));
|
||||
if (file.open(QFile::WriteOnly | QFile::Truncate)) {
|
||||
QTextStream out(&file);
|
||||
out << doc.toString();
|
||||
@@ -371,7 +375,7 @@ void CollapsibleGroup::dropEvent(QDropEvent *event)
|
||||
emit moveEffect(pastedEffectIndexes, currentEffectIndexes.last(), pasteInfo.groupIndex, pasteInfo.groupName);
|
||||
} else {
|
||||
// Group moved before current one
|
||||
emit moveEffect(pastedEffectIndexes, currentEffectIndexes.first(), pasteInfo.groupIndex, pasteInfo.groupName);
|
||||
emit moveEffect(pastedEffectIndexes, currentEffectIndexes.constFirst(), pasteInfo.groupIndex, pasteInfo.groupName);
|
||||
}
|
||||
event->setDropAction(Qt::MoveAction);
|
||||
event->accept();
|
||||
|
||||
@@ -33,7 +33,7 @@ class MyEditableLabel : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MyEditableLabel(QWidget *parent = Q_NULLPTR);
|
||||
explicit MyEditableLabel(QWidget *parent = nullptr);
|
||||
|
||||
protected:
|
||||
void mouseDoubleClickEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
|
||||
@@ -50,7 +50,7 @@ class CollapsibleGroup : public AbstractCollapsibleWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CollapsibleGroup(int ix, bool firstGroup, bool lastGroup, const EffectInfo &info, QWidget *parent = Q_NULLPTR);
|
||||
CollapsibleGroup(int ix, bool firstGroup, bool lastGroup, const EffectInfo &info, QWidget *parent = nullptr);
|
||||
~CollapsibleGroup();
|
||||
void updateTimecodeFormat();
|
||||
void setActive(bool activate) Q_DECL_OVERRIDE;
|
||||
|
||||
@@ -398,7 +398,7 @@ CustomLabel::CustomLabel(const QString &label, bool showSlider, int range, QWidg
|
||||
//m_precision(pow(10, precision)),
|
||||
{
|
||||
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
|
||||
setFormat(' ' + label);
|
||||
setFormat(QLatin1Char(' ') + label);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
setCursor(Qt::PointingHandCursor);
|
||||
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
|
||||
@@ -408,7 +408,7 @@ CustomLabel::CustomLabel(const QString &label, bool showSlider, int range, QWidg
|
||||
setRange(0, range);
|
||||
QSize sh;
|
||||
const QFontMetrics &fm = fontMetrics();
|
||||
sh.setWidth(fm.width(' ' + label + ' '));
|
||||
sh.setWidth(fm.width(QLatin1Char(' ') + label + QLatin1Char(' ')));
|
||||
setMaximumWidth(sh.width());
|
||||
setObjectName(QStringLiteral("dragOnly"));
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class CustomLabel : public QProgressBar
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CustomLabel(const QString &label, bool showSlider = true, int range = 1000, QWidget *parent = Q_NULLPTR);
|
||||
explicit CustomLabel(const QString &label, bool showSlider = true, int range = 1000, QWidget *parent = nullptr);
|
||||
void setProgressValue(double value);
|
||||
void setStep(double step);
|
||||
|
||||
@@ -83,7 +83,7 @@ public:
|
||||
* @param suffix The suffix that will be displayed in the spinbox (for example '%')
|
||||
* @param showSlider If disabled, user can still drag on the label but no progress bar is shown
|
||||
*/
|
||||
explicit DragValue(const QString &label, double defaultValue, int decimals, double min = 0, double max = 100, int id = -1, const QString &suffix = QString(), bool showSlider = true, QWidget *parent = Q_NULLPTR);
|
||||
explicit DragValue(const QString &label, double defaultValue, int decimals, double min = 0, double max = 100, int id = -1, const QString &suffix = QString(), bool showSlider = true, QWidget *parent = nullptr);
|
||||
virtual ~DragValue();
|
||||
|
||||
/** @brief Returns the precision = number of decimals */
|
||||
|
||||
@@ -181,12 +181,12 @@ MonitorSceneType EffectStackEdit::needsMonitorEffectScene() const
|
||||
return m_paramWidget->needsMonitorEffectScene();
|
||||
}
|
||||
|
||||
void EffectStackEdit::setKeyframes(const QString &tag, const QString &data)
|
||||
void EffectStackEdit::setKeyframes(const QString &tag, const QString &keyframes)
|
||||
{
|
||||
if (!m_paramWidget) {
|
||||
return;
|
||||
}
|
||||
m_paramWidget->setKeyframes(tag, data);
|
||||
m_paramWidget->setKeyframes(tag, keyframes);
|
||||
}
|
||||
|
||||
bool EffectStackEdit::doesAcceptDrops() const
|
||||
@@ -197,16 +197,16 @@ bool EffectStackEdit::doesAcceptDrops() const
|
||||
return m_paramWidget->doesAcceptDrops();
|
||||
}
|
||||
|
||||
void EffectStackEdit::importKeyframes(const QString &keyframes)
|
||||
void EffectStackEdit::importKeyframes(const QString &kf)
|
||||
{
|
||||
QMap<QString, QString> data;
|
||||
if (keyframes.contains(QLatin1Char('\n'))) {
|
||||
const QStringList params = keyframes.split(QLatin1Char('\n'), QString::SkipEmptyParts);
|
||||
QMap<QString, QString> keyframes;
|
||||
if (kf.contains(QLatin1Char('\n'))) {
|
||||
const QStringList params = kf.split(QLatin1Char('\n'), QString::SkipEmptyParts);
|
||||
for (const QString ¶m : params) {
|
||||
data.insert(param.section(QLatin1Char('='), 0, 0), param.section(QLatin1Char('='), 1));
|
||||
keyframes.insert(param.section(QLatin1Char('='), 0, 0), param.section(QLatin1Char('='), 1));
|
||||
}
|
||||
} else {
|
||||
data.insert(keyframes.section(QLatin1Char('='), 0, 0), keyframes.section(QLatin1Char('='), 1));
|
||||
keyframes.insert(kf.section(QLatin1Char('='), 0, 0), kf.section(QLatin1Char('='), 1));
|
||||
}
|
||||
emit importClipKeyframes(TransitionWidget, data);
|
||||
emit importClipKeyframes(TransitionWidget, keyframes);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class EffectStackEdit : public QScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit EffectStackEdit(Monitor *monitor, QWidget *parent = Q_NULLPTR);
|
||||
explicit EffectStackEdit(Monitor *monitor, QWidget *parent = nullptr);
|
||||
~EffectStackEdit();
|
||||
static QMap<QString, QImage> iconCache;
|
||||
/** @brief Sets attribute @param name to @param value.
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
/** @brief Returns type of monitor scene requested by this transition. */
|
||||
MonitorSceneType needsMonitorEffectScene() const;
|
||||
/** @brief Set keyframes for this transition. */
|
||||
void setKeyframes(const QString &tag, const QString &data);
|
||||
void setKeyframes(const QString &tag, const QString &keyframes);
|
||||
void updatePalette();
|
||||
/** @brief Emit geometry settings. */
|
||||
void initEffectScene(int pos);
|
||||
@@ -72,7 +72,7 @@ public slots:
|
||||
|
||||
private slots:
|
||||
/** @brief Import keyframes for the transition. */
|
||||
void importKeyframes(const QString &keyframes);
|
||||
void importKeyframes(const QString &kf);
|
||||
|
||||
signals:
|
||||
void parameterChanged(const QDomElement &, const QDomElement &, int);
|
||||
@@ -86,7 +86,7 @@ signals:
|
||||
void effectStateChanged(bool enabled);
|
||||
/** @brief Start an MLT filter job on this clip. */
|
||||
void startFilterJob(QMap<QString, QString> &, QMap<QString, QString> &, QMap<QString, QString> &);
|
||||
void importClipKeyframes(GraphicsRectItem = AVWidget, const QMap<QString, QString> &data = QMap<QString, QString>());
|
||||
void importClipKeyframes(GraphicsRectItem = AVWidget, const QMap<QString, QString> &keyframes = QMap<QString, QString>());
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -285,7 +285,6 @@ void EffectStackView2::slotTrackItemSelected(int ix, const TrackInfo &info, Moni
|
||||
m_effectMetaInfo.monitor = m;
|
||||
m_currentEffectList = info.effectsList;
|
||||
m_trackInfo = info;
|
||||
m_clipref = nullptr;
|
||||
m_masterclipref = nullptr;
|
||||
QString trackName = info.trackName.isEmpty() ? QString::number(ix) : info.trackName;
|
||||
m_effect->setLabel(i18n("Effects for track %1", trackName), trackName);
|
||||
@@ -593,9 +592,7 @@ void EffectStackView2::startDrag()
|
||||
QDrag *drag = new QDrag(this);
|
||||
drag->setPixmap(pixmap);
|
||||
QMimeData *mime = new QMimeData;
|
||||
QByteArray data;
|
||||
data.append(doc.toString().toUtf8());
|
||||
mime->setData(QStringLiteral("kdenlive/effectslist"), data);
|
||||
mime->setData(QStringLiteral("kdenlive/effectslist"), doc.toString().toUtf8());
|
||||
|
||||
// Assign ownership of the QMimeData object to the QDrag object.
|
||||
drag->setMimeData(mime);
|
||||
@@ -779,16 +776,16 @@ CollapsibleEffect *EffectStackView2::getEffectByIndex(int ix)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EffectStackView2::slotUpdateEffectParams(const QDomElement &old, const QDomElement &e, int ix)
|
||||
void EffectStackView2::slotUpdateEffectParams(const QDomElement &old, const QDomElement &e, int ix, bool update)
|
||||
{
|
||||
if (m_status == TIMELINE_TRACK) {
|
||||
emit updateEffect(nullptr, m_trackindex, old, e, ix, false);
|
||||
emit updateEffect(nullptr, m_trackindex, old, e, ix, false, update);
|
||||
} else if (m_status == TIMELINE_CLIP && m_clipref) {
|
||||
emit updateEffect(m_clipref, -1, old, e, ix, false);
|
||||
emit updateEffect(m_clipref, -1, old, e, ix, false, update);
|
||||
// Make sure the changed effect is currently displayed
|
||||
slotSetCurrentEffect(ix);
|
||||
} else if (m_status == MASTER_CLIP) {
|
||||
emit updateMasterEffect(m_masterclipref->clipId(), old, e, ix);
|
||||
emit updateMasterEffect(m_masterclipref->clipId(), old, e, ix, false, update);
|
||||
}
|
||||
m_scrollTimer.start();
|
||||
}
|
||||
@@ -867,7 +864,7 @@ void EffectStackView2::slotAddEffect(const QDomElement &effect)
|
||||
|
||||
void EffectStackView2::slotMoveEffectUp(const QList<int> &indexes, bool up)
|
||||
{
|
||||
if (up && indexes.first() <= 1) {
|
||||
if (up && indexes.constFirst() <= 1) {
|
||||
return;
|
||||
}
|
||||
if (!up && indexes.last() >= m_currentEffectList.count()) {
|
||||
@@ -875,7 +872,7 @@ void EffectStackView2::slotMoveEffectUp(const QList<int> &indexes, bool up)
|
||||
}
|
||||
int endPos;
|
||||
if (up) {
|
||||
endPos = getPreviousIndex(indexes.first());
|
||||
endPos = getPreviousIndex(indexes.constFirst());
|
||||
} else {
|
||||
endPos = getNextIndex(indexes.last());
|
||||
}
|
||||
@@ -960,7 +957,7 @@ void EffectStackView2::slotResetEffect(int ix)
|
||||
emit updateEffect(m_clipref, -1, old, dom, ix, true);
|
||||
} else if (m_status == MASTER_CLIP) {
|
||||
m_masterclipref->initEffect(m_effectMetaInfo.monitor->profileInfo(), dom);
|
||||
emit updateMasterEffect(m_masterclipref->clipId(), old, dom, ix);
|
||||
emit updateMasterEffect(m_masterclipref->clipId(), old, dom, ix,true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1228,11 +1225,11 @@ void EffectStackView2::dropEvent(QDropEvent *event)
|
||||
processDroppedEffect(doc.documentElement(), event);
|
||||
}
|
||||
|
||||
void EffectStackView2::setKeyframes(const QString &tag, const QString &data)
|
||||
void EffectStackView2::setKeyframes(const QString &tag, const QString &keyframes)
|
||||
{
|
||||
for (int i = 0; i < m_effects.count(); ++i) {
|
||||
if (m_effects.at(i)->isActive()) {
|
||||
m_effects.at(i)->setKeyframes(tag, data);
|
||||
m_effects.at(i)->setKeyframes(tag, keyframes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ class EffectStackView2 : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EffectStackView2(Monitor *projectMonitor, QWidget *parent = Q_NULLPTR);
|
||||
explicit EffectStackView2(Monitor *projectMonitor, QWidget *parent = nullptr);
|
||||
virtual ~EffectStackView2();
|
||||
|
||||
/** @brief Raises @param dock if a clip is loaded. */
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
static const QString getStyleSheet();
|
||||
|
||||
/** @brief Import keyframes from the clip metadata */
|
||||
void setKeyframes(const QString &tag, const QString &data);
|
||||
void setKeyframes(const QString &tag, const QString &keyframes);
|
||||
|
||||
/** @brief Returns the transition setting widget for signal/slot connections */
|
||||
TransitionSettings *transitionConfig();
|
||||
@@ -113,10 +113,10 @@ private:
|
||||
/** @brief The track index of currently edited track. */
|
||||
int m_trackindex;
|
||||
|
||||
/** @brief The effect currently being dragged, Q_NULLPTR if no drag happening. */
|
||||
/** @brief The effect currently being dragged, nullptr if no drag happening. */
|
||||
CollapsibleEffect *m_draggedEffect;
|
||||
|
||||
/** @brief The effect currently being dragged, Q_NULLPTR if no drag happening. */
|
||||
/** @brief The effect currently being dragged, nullptr if no drag happening. */
|
||||
CollapsibleGroup *m_draggedGroup;
|
||||
|
||||
/** @brief The current number of groups. */
|
||||
@@ -163,19 +163,19 @@ private:
|
||||
public slots:
|
||||
/** @brief Sets the clip whose effect list should be managed.
|
||||
* @param c Clip whose effect list should be managed */
|
||||
void slotClipItemSelected(ClipItem *c, Monitor *m = Q_NULLPTR, bool reloadStack = true);
|
||||
void slotClipItemSelected(ClipItem *c, Monitor *m = nullptr, bool reloadStack = true);
|
||||
/** @brief An effect parameter was changed, refresh effect stack if it was displaying it.
|
||||
* @param c Clip controller whose effect list should be managed */
|
||||
void slotRefreshMasterClipEffects(ClipController *c, Monitor *m);
|
||||
/** @brief Display effects for the selected Bin clip.
|
||||
* @param c Clip controller whose effect list should be managed */
|
||||
void slotMasterClipItemSelected(ClipController *c, Monitor *m = Q_NULLPTR);
|
||||
void slotMasterClipItemSelected(ClipController *c, Monitor *m = nullptr);
|
||||
|
||||
/** @brief Update the clip range (in-out points)
|
||||
* @param c Clip whose effect list should be managed */
|
||||
void slotClipItemUpdate();
|
||||
|
||||
void slotTrackItemSelected(int ix, const TrackInfo &info, Monitor *m = Q_NULLPTR);
|
||||
void slotTrackItemSelected(int ix, const TrackInfo &info, Monitor *m = nullptr);
|
||||
|
||||
/** @brief Check if the mouse wheel events should be used for scrolling the widget view. */
|
||||
void slotCheckWheelEventFilter();
|
||||
@@ -196,7 +196,7 @@ private slots:
|
||||
/** @brief Checks whether the monitor scene has to be displayed. */
|
||||
void slotCheckMonitorPosition(int renderPos);
|
||||
|
||||
void slotUpdateEffectParams(const QDomElement &old, const QDomElement &e, int ix);
|
||||
void slotUpdateEffectParams(const QDomElement &old, const QDomElement &e, int ix, bool update);
|
||||
|
||||
/** @brief Move an effect in the stack.
|
||||
* @param indexes The list of effect index in the stack
|
||||
@@ -261,9 +261,9 @@ signals:
|
||||
void removeMasterEffect(const QString &id, const QDomElement &);
|
||||
void addMasterEffect(const QString &id, const QDomElement &);
|
||||
/** Parameters for an effect changed, update the filter in timeline */
|
||||
void updateEffect(ClipItem *, int, const QDomElement &, const QDomElement &, int, bool);
|
||||
void updateEffect(ClipItem *, int, const QDomElement &, const QDomElement &, int, bool refreshStack, bool updateClip = true);
|
||||
/** Parameters for an effect changed, update the filter in timeline */
|
||||
void updateMasterEffect(QString, const QDomElement &, const QDomElement &, int);
|
||||
void updateMasterEffect(QString, const QDomElement &, const QDomElement &, int ix,bool refreshStack = false, bool updateClip = true);
|
||||
/** An effect in stack was moved, we need to regenerate
|
||||
all effects for this clip in the playlist */
|
||||
void refreshEffectStack(ClipItem *);
|
||||
@@ -284,7 +284,7 @@ signals:
|
||||
void showComments(bool show);
|
||||
void startFilterJob(const ItemInfo &info, const QString &clipId, QMap<QString, QString> &, QMap<QString, QString> &, QMap<QString, QString> &);
|
||||
void addEffect(ClipItem *, const QDomElement &, int);
|
||||
void importClipKeyframes(GraphicsRectItem, ItemInfo, const QDomElement &, const QMap<QString, QString> &data = QMap<QString, QString>());
|
||||
void importClipKeyframes(GraphicsRectItem, ItemInfo, const QDomElement &, const QMap<QString, QString> &keyframes = QMap<QString, QString>());
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -174,7 +174,7 @@ void MyTextItem::updateGeometry(int, int, int)
|
||||
double lineSpacing = data(TitleDocument::LineSpacing).toInt() + metrics.lineSpacing();
|
||||
|
||||
// Calculate line width
|
||||
QStringList lines = text.split('\n');
|
||||
const QStringList lines = text.split(QLatin1Char('\n'));
|
||||
double linePos = metrics.ascent();
|
||||
QRectF bounding = boundingRect();
|
||||
/*if (lines.count() > 0) {
|
||||
@@ -495,6 +495,7 @@ GraphicsSceneRectMove::GraphicsSceneRectMove(QObject *parent) :
|
||||
m_tool(TITLE_RECTANGLE),
|
||||
m_gridSize(20),
|
||||
m_createdText(false),
|
||||
m_moveStarted(false),
|
||||
m_pan(false)
|
||||
{
|
||||
//grabMouse();
|
||||
@@ -605,7 +606,7 @@ void GraphicsSceneRectMove::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *e)
|
||||
}
|
||||
|
||||
int ix = 1;
|
||||
QGraphicsItem *g = i.first();
|
||||
QGraphicsItem *g = i.constFirst();
|
||||
while (!(g->flags() & QGraphicsItem::ItemIsSelectable) && ix < i.count()) {
|
||||
g = i.at(ix);
|
||||
ix++;
|
||||
@@ -639,7 +640,7 @@ void GraphicsSceneRectMove::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
|
||||
}
|
||||
QList<QGraphicsView*> viewlist = views();
|
||||
if (!viewlist.isEmpty()) {
|
||||
viewlist.first()->setDragMode(QGraphicsView::RubberBandDrag);
|
||||
viewlist.constFirst()->setDragMode(QGraphicsView::RubberBandDrag);
|
||||
}
|
||||
emit actionFinished();
|
||||
}
|
||||
@@ -650,7 +651,7 @@ void GraphicsSceneRectMove::mousePressEvent(QGraphicsSceneMouseEvent *e)
|
||||
clearTextSelection();
|
||||
QList<QGraphicsView*> viewlist = views();
|
||||
if (!viewlist.isEmpty()) {
|
||||
viewlist.first()->setDragMode(QGraphicsView::ScrollHandDrag);
|
||||
viewlist.constFirst()->setDragMode(QGraphicsView::ScrollHandDrag);
|
||||
m_pan = true;
|
||||
e->accept();
|
||||
QGraphicsScene::mousePressEvent(e);
|
||||
@@ -669,17 +670,16 @@ void GraphicsSceneRectMove::mousePressEvent(QGraphicsSceneMouseEvent *e)
|
||||
if (e->modifiers() & Qt::ControlModifier) {
|
||||
clearTextSelection();
|
||||
if (!viewlist.isEmpty()) {
|
||||
viewlist.first()->setDragMode(QGraphicsView::ScrollHandDrag);
|
||||
viewlist.constFirst()->setDragMode(QGraphicsView::ScrollHandDrag);
|
||||
e->ignore();
|
||||
//QGraphicsScene::mousePressEvent(e);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!viewlist.isEmpty()) {
|
||||
viewlist.first()->setRubberBandSelectionMode(Qt::IntersectsItemShape);
|
||||
viewlist.constFirst()->setRubberBandSelectionMode(Qt::IntersectsItemShape);
|
||||
}
|
||||
}
|
||||
QList<QGraphicsItem *> selected = selectedItems();
|
||||
bool alreadySelected = false;
|
||||
foreach(QGraphicsItem *g, list) {
|
||||
//qDebug() << " - - CHECKING ITEM Z:" << g->zValue() << ", TYPE: " << g->type();
|
||||
@@ -689,14 +689,19 @@ void GraphicsSceneRectMove::mousePressEvent(QGraphicsSceneMouseEvent *e)
|
||||
}
|
||||
if (g->zValue() > -1000/* && g->isSelected()*/) {
|
||||
alreadySelected = g->isSelected();
|
||||
g->setSelected(true);
|
||||
if (!alreadySelected) {
|
||||
g->setSelected(true);
|
||||
}
|
||||
item = g;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (item == nullptr || (e->modifiers() != Qt::ShiftModifier && !alreadySelected)) {
|
||||
clearTextSelection();
|
||||
} else if (item && item->flags() & QGraphicsItem::ItemIsMovable) {
|
||||
} else if (e->modifiers() & Qt::ShiftModifier) {
|
||||
clearTextSelection(false);
|
||||
}
|
||||
if (item && item->flags() & QGraphicsItem::ItemIsMovable) {
|
||||
m_sceneClickPoint = e->scenePos();
|
||||
m_selectedItem = item;
|
||||
//qCDebug(KDENLIVE_LOG) << "///////// ITEM TYPE: " << item->type();
|
||||
@@ -767,7 +772,7 @@ void GraphicsSceneRectMove::mousePressEvent(QGraphicsSceneMouseEvent *e)
|
||||
//qCDebug(KDENLIVE_LOG) << "////// MOUSE CLICK, RESIZE MODE: " << m_resizeMode;
|
||||
}
|
||||
|
||||
void GraphicsSceneRectMove::clearTextSelection()
|
||||
void GraphicsSceneRectMove::clearTextSelection(bool reset)
|
||||
{
|
||||
if (m_selectedItem && m_selectedItem->type() == QGraphicsTextItem::Type) {
|
||||
// disable text editing
|
||||
@@ -777,8 +782,10 @@ void GraphicsSceneRectMove::clearTextSelection()
|
||||
t->setTextCursor(QTextCursor(cur));
|
||||
t->setTextInteractionFlags(Qt::NoTextInteraction);
|
||||
}
|
||||
m_selectedItem = nullptr;
|
||||
clearSelection();
|
||||
if (reset) {
|
||||
m_selectedItem = nullptr;
|
||||
clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsSceneRectMove::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
|
||||
@@ -788,7 +795,7 @@ void GraphicsSceneRectMove::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
|
||||
e->ignore();
|
||||
return;
|
||||
}
|
||||
QGraphicsView *view = viewlist.first();
|
||||
QGraphicsView *view = viewlist.constFirst();
|
||||
if (m_pan) {
|
||||
QPoint diff = e->lastScreenPos() - e->screenPos();
|
||||
view->horizontalScrollBar()->setValue(view->horizontalScrollBar()->value() + diff.x());
|
||||
@@ -800,7 +807,6 @@ void GraphicsSceneRectMove::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
|
||||
if (e->buttons() != Qt::NoButton && !m_moveStarted) {
|
||||
if ((view->mapFromScene(e->scenePos()) - view->mapFromScene(m_clickPoint)).manhattanLength() < QApplication::startDragDistance()) {
|
||||
e->ignore();
|
||||
QGraphicsScene::mouseMoveEvent(e);
|
||||
return;
|
||||
} else {
|
||||
m_moveStarted = true;
|
||||
|
||||
@@ -32,7 +32,7 @@ enum TITLETOOL { TITLE_SELECT = 0, TITLE_RECTANGLE = 1, TITLE_TEXT = 2, TITLE_IM
|
||||
class MyQGraphicsEffect: public QGraphicsEffect
|
||||
{
|
||||
public:
|
||||
explicit MyQGraphicsEffect(QObject *parent = Q_NULLPTR);
|
||||
explicit MyQGraphicsEffect(QObject *parent = nullptr);
|
||||
void setOffset(int xOffset, int yOffset, int blur);
|
||||
void setShadow(const QImage &image);
|
||||
protected:
|
||||
@@ -48,7 +48,7 @@ class MyTextItem: public QGraphicsTextItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyTextItem(const QString &, QGraphicsItem *parent = Q_NULLPTR);
|
||||
MyTextItem(const QString &, QGraphicsItem *parent = nullptr);
|
||||
void setAlignment(Qt::Alignment alignment);
|
||||
/** @brief returns an extended bounding containing shadow */
|
||||
QRectF boundingRect() const Q_DECL_OVERRIDE;
|
||||
@@ -84,7 +84,7 @@ public slots:
|
||||
class MyRectItem: public QGraphicsRectItem
|
||||
{
|
||||
public:
|
||||
explicit MyRectItem(QGraphicsItem *parent = Q_NULLPTR);
|
||||
explicit MyRectItem(QGraphicsItem *parent = nullptr);
|
||||
void setRect(const QRectF &rectangle);
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) Q_DECL_OVERRIDE;
|
||||
@@ -95,7 +95,7 @@ private:
|
||||
class MyPixmapItem: public QGraphicsPixmapItem
|
||||
{
|
||||
public:
|
||||
MyPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = Q_NULLPTR);
|
||||
MyPixmapItem(const QPixmap &pixmap, QGraphicsItem *parent = nullptr);
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) Q_DECL_OVERRIDE;
|
||||
};
|
||||
@@ -103,7 +103,7 @@ protected:
|
||||
class MySvgItem: public QGraphicsSvgItem
|
||||
{
|
||||
public:
|
||||
MySvgItem(const QString &fileName = QString(), QGraphicsItem *parent = Q_NULLPTR);
|
||||
MySvgItem(const QString &fileName = QString(), QGraphicsItem *parent = nullptr);
|
||||
protected:
|
||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value) Q_DECL_OVERRIDE;
|
||||
};
|
||||
@@ -112,13 +112,14 @@ class GraphicsSceneRectMove: public QGraphicsScene
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit GraphicsSceneRectMove(QObject *parent = Q_NULLPTR);
|
||||
explicit GraphicsSceneRectMove(QObject *parent = nullptr);
|
||||
void setSelectedItem(QGraphicsItem *item);
|
||||
void setScale(double s);
|
||||
void setZoom(double s);
|
||||
void setTool(TITLETOOL tool);
|
||||
TITLETOOL tool() const;
|
||||
void clearTextSelection();
|
||||
/** @brief Get out of text edit mode. If reset is true, we also unselect all items */
|
||||
void clearTextSelection(bool reset = true);
|
||||
int gridSize() const;
|
||||
void addNewItem(QGraphicsItem *item);
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class KeyframeHelper : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit KeyframeHelper(QWidget *parent = Q_NULLPTR);
|
||||
explicit KeyframeHelper(QWidget *parent = nullptr);
|
||||
int value() const;
|
||||
int frameLength;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user