Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Multimedia
Kdenlive
Commits
20407bda
Commit
20407bda
authored
Oct 29, 2017
by
Nicolas Carion
Browse files
Huge cleanup of clip creation and jobs
parent
f100d136
Changes
82
Expand all
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
20407bda
...
...
@@ -129,7 +129,7 @@ if (BUILD_TESTS)
message
(
STATUS
"Building TESTS"
)
add_subdirectory
(
tests
)
SET
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-std=c++1
1
-Wall -fexceptions"
)
SET
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-std=c++1
4
-Wall -fexceptions"
)
include_directories
(
${
CMAKE_BINARY_DIR
}
${
CMAKE_BINARY_DIR
}
/src
...
...
src/CMakeLists.txt
View file @
20407bda
...
...
@@ -15,7 +15,7 @@ else()
PURPOSE
""
)
endif
()
SET
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-std=c++1
1
-Wall -pedantic -Wextra"
)
SET
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-std=c++1
4
-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"
)
...
...
@@ -25,6 +25,7 @@ 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"
)
SET
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-Wno-undef"
)
if
(
CMAKE_COMPILER_IS_GNUCXX
)
SET
(
CMAKE_CXX_FLAGS
"
${
CMAKE_CXX_FLAGS
}
-Wlogical-op -Wunsafe-loop-optimizations "
)
endif
()
...
...
@@ -96,6 +97,7 @@ add_subdirectory(doc)
add_subdirectory
(
dvdwizard
)
add_subdirectory
(
effects
)
add_subdirectory
(
effectslist
)
add_subdirectory
(
jobs
)
add_subdirectory
(
lib
)
add_subdirectory
(
mltcontroller
)
add_subdirectory
(
monitor
)
...
...
src/abstractmodel/treeitem.cpp
View file @
20407bda
...
...
@@ -152,7 +152,7 @@ bool TreeItem::changeParent(std::shared_ptr<TreeItem> newParent)
Q_ASSERT
(
!
m_isRoot
);
if
(
m_isRoot
)
return
false
;
std
::
shared_ptr
<
TreeItem
>
oldParent
;
if
(
oldParent
=
m_parentItem
.
lock
())
{
if
(
(
oldParent
=
m_parentItem
.
lock
())
)
{
oldParent
->
removeChild
(
shared_from_this
());
}
bool
res
=
true
;
...
...
src/bin/abstractprojectitem.cpp
View file @
20407bda
...
...
@@ -22,6 +22,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include
"abstractprojectitem.h"
#include
"bin.h"
#include
"core.h"
#include
"jobs/jobmanager.h"
#include
"macros.hpp"
#include
"projectitemmodel.h"
...
...
@@ -38,29 +40,11 @@ AbstractProjectItem::AbstractProjectItem(PROJECTITEMTYPE type, const QString &id
,
m_binId
(
id
)
,
m_usage
(
0
)
,
m_clipStatus
(
StatusReady
)
,
m_jobType
(
AbstractClipJob
::
NOJOBTYPE
)
,
m_jobProgress
(
0
)
,
m_itemType
(
type
)
,
m_isCurrent
(
false
)
,
m_lock
(
QReadWriteLock
::
Recursive
)
{
}
AbstractProjectItem
::
AbstractProjectItem
(
PROJECTITEMTYPE
type
,
const
QString
&
id
,
const
QDomElement
&
description
,
const
std
::
shared_ptr
<
ProjectItemModel
>
&
model
)
:
TreeItem
(
QList
<
QVariant
>
(),
std
::
static_pointer_cast
<
AbstractTreeModel
>
(
model
),
false
)
,
m_name
()
,
m_description
()
,
m_thumbnail
(
QIcon
())
,
m_date
()
,
m_binId
(
id
)
,
m_usage
(
0
)
,
m_clipStatus
(
StatusReady
)
,
m_jobType
(
AbstractClipJob
::
NOJOBTYPE
)
,
m_jobProgress
(
0
)
,
m_itemType
(
type
)
,
m_isCurrent
(
false
)
,
m_lock
(
QReadWriteLock
::
Recursive
)
{
Q_ASSERT
(
!
isRoot
||
type
==
FolderItem
);
}
bool
AbstractProjectItem
::
operator
==
(
const
std
::
shared_ptr
<
AbstractProjectItem
>
&
projectItem
)
const
...
...
@@ -155,13 +139,52 @@ QVariant AbstractProjectItem::getData(DataType type) const
data
=
QVariant
(
m_itemType
);
break
;
case
JobType
:
data
=
QVariant
(
m_jobType
);
if
(
itemType
()
==
ClipItem
)
{
auto
jobIds
=
pCore
->
jobManager
()
->
getPendingJobsIds
(
clipId
());
if
(
jobIds
.
empty
())
{
jobIds
=
pCore
->
jobManager
()
->
getFinishedJobsIds
(
clipId
());
}
if
(
jobIds
.
size
()
>
0
)
{
data
=
QVariant
(
pCore
->
jobManager
()
->
getJobType
(
jobIds
[
0
]));
}
}
break
;
case
JobStatus
:
if
(
itemType
()
==
ClipItem
)
{
auto
jobIds
=
pCore
->
jobManager
()
->
getPendingJobsIds
(
clipId
());
if
(
jobIds
.
empty
())
{
jobIds
=
pCore
->
jobManager
()
->
getFinishedJobsIds
(
clipId
());
}
if
(
jobIds
.
size
()
>
0
)
{
data
=
QVariant
(
pCore
->
jobManager
()
->
getJobType
(
jobIds
[
0
]));
}
else
{
data
=
QVariant
::
fromValue
(
JobStatus
::
NoJob
);
}
}
break
;
case
JobProgress
:
data
=
QVariant
(
m_jobProgress
);
if
(
itemType
()
==
ClipItem
)
{
auto
jobIds
=
pCore
->
jobManager
()
->
getPendingJobsIds
(
clipId
());
if
(
jobIds
.
size
()
>
0
)
{
data
=
QVariant
(
pCore
->
jobManager
()
->
getJobProgressForClip
(
jobIds
[
0
],
clipId
()));
}
else
{
data
=
QVariant
(
0
);
}
}
break
;
case
JobMessage
:
data
=
QVariant
(
m_jobMessage
);
if
(
itemType
()
==
ClipItem
)
{
QString
messages
;
auto
jobIds
=
pCore
->
jobManager
()
->
getPendingJobsIds
(
clipId
());
for
(
int
job
:
jobIds
)
{
messages
.
append
(
pCore
->
jobManager
()
->
getJobMessageForClip
(
job
,
clipId
()));
}
jobIds
=
pCore
->
jobManager
()
->
getFinishedJobsIds
(
clipId
());
for
(
int
job
:
jobIds
)
{
messages
.
append
(
pCore
->
jobManager
()
->
getJobMessageForClip
(
job
,
clipId
()));
}
data
=
QVariant
(
messages
);
}
break
;
case
ClipStatus
:
data
=
QVariant
(
m_clipStatus
);
...
...
src/bin/abstractprojectitem.h
View file @
20407bda
...
...
@@ -24,7 +24,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define ABSTRACTPROJECTITEM_H
#include
"abstractmodel/treeitem.hpp"
#include
"project/jobs/abstractclipjob.h"
#include
"undohelper.hpp"
#include
<QDateTime>
...
...
@@ -60,15 +59,6 @@ public:
* @param isRoot is true if this is the topmost folder
*/
AbstractProjectItem
(
PROJECTITEMTYPE
type
,
const
QString
&
id
,
const
std
::
shared_ptr
<
ProjectItemModel
>
&
model
,
bool
isRoot
=
false
);
/**
* @brief Creates a project item upon project load.
* @param description element for this item.
* @param model pointer to the model this item is added to.
* @param parent parent this item should be added to
*
* We try to read the attributes "name" and "description"
*/
AbstractProjectItem
(
PROJECTITEMTYPE
type
,
const
QString
&
id
,
const
QDomElement
&
description
,
const
std
::
shared_ptr
<
ProjectItemModel
>
&
model
);
bool
operator
==
(
const
std
::
shared_ptr
<
AbstractProjectItem
>
&
projectItem
)
const
;
...
...
@@ -136,6 +126,7 @@ public:
JobProgress
,
// error message if job crashes (not fully implemented)
JobMessage
,
JobStatus
,
// Item status (ready or not, missing, waiting, ...)
ClipStatus
};
...
...
@@ -206,10 +197,7 @@ protected:
QString
m_binId
;
uint
m_usage
;
CLIPSTATUS
m_clipStatus
;
AbstractClipJob
::
JOBTYPE
m_jobType
;
int
m_jobProgress
;
QString
m_jobMessage
;
PROJECTITEMTYPE
m_itemType
;
QString
m_lastParentId
;
...
...
src/bin/bin.cpp
View file @
20407bda
This diff is collapsed.
Click to expand it.
src/bin/bin.h
View file @
20407bda
...
...
@@ -24,9 +24,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KDENLIVE_BIN_H
#include
"abstractprojectitem.h"
#include
"timecode.h"
#include
"filewatcher.hpp"
#include
"effects/effectstack/model/effectstackmodel.hpp"
#include
"filewatcher.hpp"
#include
"timecode.h"
#include
<KMessageWidget>
...
...
@@ -59,7 +59,6 @@ class ProjectFolder;
class
AbstractProjectItem
;
class
Monitor
;
class
ProjectSortProxyModel
;
class
JobManager
;
class
ProjectFolderUp
;
class
InvalidDialog
;
class
BinItemDelegate
;
...
...
@@ -197,26 +196,16 @@ public:
void
openProducer
(
std
::
shared_ptr
<
ProjectClip
>
controller
);
void
openProducer
(
std
::
shared_ptr
<
ProjectClip
>
controller
,
int
in
,
int
out
);
/** @brief Trigger deletion of an item */
void
deleteClip
(
const
QString
&
id
);
/** @brief Get a clip from it's id */
std
::
shared_ptr
<
ProjectClip
>
getBinClip
(
const
QString
&
id
);
/** @brief Returns a list of selected clips */
QList
<
std
::
shared_ptr
<
ProjectClip
>>
selectedClips
();
/** @brief Start a job of selected type for a clip */
void
startJob
(
const
QString
&
id
,
AbstractClipJob
::
JOBTYPE
type
);
/** @brief Discard jobs from a chosen type, use NOJOBTYPE to discard all jobs for this clip */
void
discardJobs
(
const
QString
&
id
,
AbstractClipJob
::
JOBTYPE
type
=
AbstractClipJob
::
NOJOBTYPE
);
/** @brief Check if there is a job waiting / running for this clip */
bool
hasPendingJob
(
const
QString
&
id
,
AbstractClipJob
::
JOBTYPE
type
);
/** @brief Returns a list of selected clip ids
@param excludeFolders: if true, ids of folders are not returned
*/
std
::
vector
<
QString
>
selectedClipsIds
(
bool
excludeFolders
=
true
);
/
** @brief Reload / replace a producer */
void
reloadProducer
(
const
QString
&
id
,
const
QDomElement
&
xml
);
/
/ Returns the selected clips
QList
<
std
::
shared_ptr
<
ProjectClip
>>
selectedClips
(
);
/** @brief Current producer has changed, refresh monitor and timeline*/
void
refreshClip
(
const
QString
&
id
);
...
...
@@ -243,15 +232,9 @@ public:
/** @brief Ask MLT to reload this clip's producer */
void
reloadClip
(
const
QString
&
id
);
/** @brief Add a folder */
void
removeSubClip
(
const
QString
&
id
,
QUndoCommand
*
deleteCommand
);
void
doMoveClip
(
const
QString
&
id
,
const
QString
&
newParentId
);
void
doMoveFolder
(
const
QString
&
id
,
const
QString
&
newParentId
);
void
setupGeneratorMenu
();
void
startClipJob
(
const
QStringList
&
params
);
void
addClipCut
(
const
QString
&
id
,
int
in
,
int
out
);
void
removeClipCut
(
const
QString
&
id
,
int
in
,
int
out
);
/** @brief Set focus to the Bin view. */
void
focusBinView
()
const
;
...
...
@@ -283,8 +266,6 @@ public:
void
refreshProxySettings
();
/** @brief A clip is ready, update its info panel if displayed. */
void
emitRefreshPanel
(
const
QString
&
id
);
/** @brief Audio thumbs just finished creating, update on monitor display. */
void
emitRefreshAudioThumbs
(
const
QString
&
id
);
/** @brief Returns true if there is no clip. */
bool
isEmpty
()
const
;
/** @brief Trigger reload of all clips. */
...
...
@@ -320,7 +301,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 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 */
...
...
@@ -333,13 +314,7 @@ private slots:
void
slotItemDropped
(
const
QList
<
QUrl
>
&
urls
,
const
QModelIndex
&
parent
);
void
slotEffectDropped
(
const
QStringList
&
effectData
,
const
QModelIndex
&
parent
);
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. */
void
slotGotFilterJobResults
(
const
QString
&
,
int
,
int
,
const
stringMap
&
,
const
stringMap
&
);
/** @brief Reset all text and log data from info message widget. */
void
slotResetInfoMessage
();
/** @brief Show dialog prompting for removal of invalid clips. */
...
...
@@ -367,11 +342,6 @@ private slots:
public
slots
:
void
slotThumbnailReady
(
const
QString
&
id
,
const
QImage
&
img
,
bool
fromFile
=
false
);
/** @brief The producer for this clip is ready.
* @param id the clip id
* @param controller The Controller for this clip
*/
void
slotProducerReady
(
const
requestClipInfo
&
info
,
std
::
shared_ptr
<
Mlt
::
Producer
>
producer
);
void
slotRemoveInvalidClip
(
const
QString
&
id
,
bool
replace
,
const
QString
&
errorMessage
);
/** @brief Reload clip thumbnail - when frame for thumbnail changed */
void
slotRefreshClipThumbnail
(
const
QString
&
id
);
...
...
@@ -382,25 +352,14 @@ public slots:
/** @brief Creates a new folder with optional name, and returns new folder's id */
QString
slotAddFolder
(
const
QString
&
folderName
=
QString
());
void
slotCreateProjectClip
();
/** @brief Start a Cut Clip job on this clip (extract selected zone using FFmpeg) */
void
slotStartCutJob
(
const
QString
&
id
);
/** @brief Triggered by a clip job action, start the job */
void
slotStartClipJob
(
bool
enable
);
void
slotEditClipCommand
(
const
QString
&
id
,
const
QMap
<
QString
,
QString
>
&
oldProps
,
const
QMap
<
QString
,
QString
>
&
newProps
);
void
slotCancelRunningJob
(
const
QString
&
id
,
const
QMap
<
QString
,
QString
>
&
newProps
);
/** @brief Start a filter job requested by a filter applied in timeline */
void
slotStartFilterJob
(
const
ItemInfo
&
info
,
const
QString
&
id
,
QMap
<
QString
,
QString
>
&
filterParams
,
QMap
<
QString
,
QString
>
&
consumerParams
,
QMap
<
QString
,
QString
>
&
extraParams
);
/** @brief Add a sub clip */
void
slotAddClipCut
(
const
QString
&
id
,
int
in
,
int
out
);
/** @brief Open current clip in an external editing application */
void
slotOpenClip
();
void
slotDuplicateClip
();
void
slotLocateClip
();
/** @brief Request audio thumbnail for clip with id */
void
slotCreateAudioThumb
(
const
QString
&
id
);
/** @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
=
nullptr
);
void
slotUpdateClipProperties
(
const
QString
&
id
,
const
QMap
<
QString
,
QString
>
&
properties
,
bool
refreshPropertiesPanel
);
...
...
@@ -411,7 +370,7 @@ public slots:
/** @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
();
...
...
@@ -423,12 +382,10 @@ public slots:
/** @brief Select a clip in the Bin from its id. */
void
selectClipById
(
const
QString
&
id
,
int
frame
=
-
1
,
const
QPoint
&
zone
=
QPoint
());
void
slotAddClipToProject
(
const
QUrl
&
url
);
void
doUpdateThumbsProgress
(
long
ms
);
void
droppedUrls
(
const
QList
<
QUrl
>
&
urls
,
const
QStringList
&
folderInfo
=
QStringList
());
/** @brief A clip producer was changed and needs to be replaced in timeline. */
void
prepareTimelineReplacement
(
const
requestClipInfo
&
info
,
const
std
::
shared_ptr
<
Mlt
::
Producer
>
&
producer
);
/** @brief Returns the effectstack of a given clip. */
std
::
shared_ptr
<
EffectStackModel
>
getClipEffectStack
(
int
itemId
);
protected:
/* This function is called whenever an item is selected to propagate signals
(for ex request to show the clip in the monitor)
...
...
@@ -445,7 +402,6 @@ private:
std
::
shared_ptr
<
ProjectFolderUp
>
m_folderUp
;
BinItemDelegate
*
m_binTreeViewDelegate
;
ProjectSortProxyModel
*
m_proxyModel
;
JobManager
*
m_jobManager
;
QToolBar
*
m_toolbar
;
KdenliveDoc
*
m_doc
;
FileWatcher
m_fileWatcher
;
...
...
@@ -530,12 +486,10 @@ signals:
void
updateAnalysisData
(
const
QString
&
);
void
openClip
(
std
::
shared_ptr
<
ProjectClip
>
c
,
int
in
=
-
1
,
int
out
=
-
1
);
/** @brief Fill context menu with occurrences of this clip in timeline. */
void
findInTimeline
(
const
QString
&
,
QList
<
int
>
ids
=
QList
<
int
>
());
void
findInTimeline
(
const
QString
&
,
QList
<
int
>
ids
=
QList
<
int
>
());
void
clipNameChanged
(
const
QString
&
);
/** @brief A clip was updated, request panel update. */
void
refreshPanel
(
const
QString
&
id
);
/** @brief A clip audio data was updated, request refresh. */
void
refreshAudioThumbs
(
const
QString
&
id
);
};
#endif
src/bin/bincommands.cpp
View file @
20407bda
...
...
@@ -86,35 +86,6 @@ void RenameBinSubClipCommand::redo()
m_bin
->
renameSubClip
(
m_clipId
,
m_newName
,
m_oldName
,
m_in
,
m_out
);
}
AddBinClipCutCommand
::
AddBinClipCutCommand
(
Bin
*
bin
,
const
QString
&
clipId
,
int
in
,
int
out
,
bool
add
,
QUndoCommand
*
parent
)
:
QUndoCommand
(
parent
)
,
m_bin
(
bin
)
,
m_clipId
(
clipId
)
,
m_in
(
in
)
,
m_out
(
out
)
,
m_addCut
(
add
)
{
setText
(
i18n
(
"Add Sub Clip"
));
}
// virtual
void
AddBinClipCutCommand
::
undo
()
{
if
(
m_addCut
)
{
m_bin
->
removeClipCut
(
m_clipId
,
m_in
,
m_out
);
}
else
{
m_bin
->
addClipCut
(
m_clipId
,
m_in
,
m_out
);
}
}
// virtual
void
AddBinClipCutCommand
::
redo
()
{
if
(
m_addCut
)
{
m_bin
->
addClipCut
(
m_clipId
,
m_in
,
m_out
);
}
else
{
m_bin
->
removeClipCut
(
m_clipId
,
m_in
,
m_out
);
}
}
EditClipCommand
::
EditClipCommand
(
Bin
*
bin
,
const
QString
&
id
,
const
QMap
<
QString
,
QString
>
&
oldparams
,
const
QMap
<
QString
,
QString
>
&
newparams
,
bool
doIt
,
QUndoCommand
*
parent
)
...
...
@@ -143,34 +114,3 @@ void EditClipCommand::redo()
m_firstExec
=
false
;
}
AddClipCommand
::
AddClipCommand
(
Bin
*
bin
,
const
QDomElement
&
xml
,
const
QString
&
id
,
bool
doIt
,
QUndoCommand
*
parent
)
:
QUndoCommand
(
parent
)
,
m_bin
(
bin
)
,
m_xml
(
xml
)
,
m_id
(
id
)
,
m_doIt
(
doIt
)
{
if
(
doIt
)
{
setText
(
i18n
(
"Add clip"
));
}
else
{
setText
(
i18n
(
"Delete clip"
));
}
}
// virtual
void
AddClipCommand
::
undo
()
{
if
(
m_doIt
)
{
m_bin
->
deleteClip
(
m_id
);
}
else
{
m_bin
->
addClip
(
m_xml
,
m_id
);
}
}
// virtual
void
AddClipCommand
::
redo
()
{
if
(
m_doIt
)
{
m_bin
->
addClip
(
m_xml
,
m_id
);
}
else
{
m_bin
->
deleteClip
(
m_id
);
}
}
src/bin/bincommands.h
View file @
20407bda
...
...
@@ -72,20 +72,6 @@ private:
int
m_out
;
};
class
AddBinClipCutCommand
:
public
QUndoCommand
{
public:
explicit
AddBinClipCutCommand
(
Bin
*
bin
,
const
QString
&
clipId
,
int
in
,
int
out
,
bool
add
,
QUndoCommand
*
parent
=
nullptr
);
void
undo
()
override
;
void
redo
()
override
;
private:
Bin
*
m_bin
;
QString
m_clipId
;
int
m_in
;
int
m_out
;
bool
m_addCut
;
};
class
EditClipCommand
:
public
QUndoCommand
{
...
...
@@ -109,18 +95,5 @@ private:
bool
m_firstExec
;
};
class
AddClipCommand
:
public
QUndoCommand
{
public:
AddClipCommand
(
Bin
*
bin
,
const
QDomElement
&
xml
,
const
QString
&
id
,
bool
doIt
,
QUndoCommand
*
parent
=
nullptr
);
void
undo
()
override
;
void
redo
()
override
;
private:
Bin
*
m_bin
;
QDomElement
m_xml
;
QString
m_id
;
bool
m_doIt
;
};
#endif
src/bin/clipcreator.cpp
View file @
20407bda
...
...
@@ -20,27 +20,236 @@
***************************************************************************/
#include
"clipcreator.hpp"
#include
"core.h"
#include
"doc/kdenlivedoc.h"
#include
"kdenlivesettings.h"
#include
"klocalizedstring.h"
#include
"macros.hpp"
#include
"projectitemmodel.h"
#include
"titler/titledocument.h"
#include
"utils/devices.hpp"
#include
"xml/xml.hpp"
#include
"klocalizedstring.h"
#include
<KMessageBox>
#include
<QApplication>
#include
<QDomDocument>
#include
<QMimeDatabase>
#include
<QWindow>
QString
ClipCreator
::
createColorClip
(
const
QString
&
color
,
int
duration
,
const
QString
&
name
,
const
QString
&
parentFolder
,
std
::
shared_ptr
<
ProjectItemModel
>
model
)
namespace
{
QDomElement
createProducer
(
QDomDocument
&
xml
,
ClipType
type
,
const
QString
&
resource
,
const
QString
&
name
,
int
duration
,
const
QString
&
service
,
const
QString
&
transparency
)
{
QDomDocument
xml
;
QDomElement
prod
=
xml
.
createElement
(
QStringLiteral
(
"producer"
));
xml
.
appendChild
(
prod
);
prod
.
setAttribute
(
QStringLiteral
(
"type"
),
(
int
)
Color
);
prod
.
setAttribute
(
QStringLiteral
(
"type"
),
(
int
)
type
);
prod
.
setAttribute
(
QStringLiteral
(
"in"
),
QStringLiteral
(
"0"
));
prod
.
setAttribute
(
QStringLiteral
(
"length"
),
duration
);
QMap
<
QString
,
QString
>
properties
;
properties
.
insert
(
QStringLiteral
(
"resource"
),
color
);
properties
.
insert
(
QStringLiteral
(
"kdenlive:clipname"
),
name
);
properties
.
insert
(
QStringLiteral
(
"mlt_service"
),
QStringLiteral
(
"color"
));
if
(
!
transparency
.
isEmpty
())
{
prod
.
setAttribute
(
QStringLiteral
(
"transparency"
),
transparency
);
}
std
::
unordered_map
<
QString
,
QString
>
properties
;
properties
[
QStringLiteral
(
"resource"
)]
=
resource
;
if
(
!
name
.
isEmpty
())
{
properties
[
QStringLiteral
(
"kdenlive:clipname"
)]
=
name
;
}
if
(
!
service
.
isEmpty
())
{
properties
[
QStringLiteral
(
"mlt_service"
)]
=
service
;
}
Xml
::
addXmlProperties
(
prod
,
properties
);
return
prod
;
}
}
// namespace
QString
ClipCreator
::
createColorClip
(
const
QString
&
color
,
int
duration
,
const
QString
&
name
,
const
QString
&
parentFolder
,
std
::
shared_ptr
<
ProjectItemModel
>
model
)
{
QDomDocument
xml
;
auto
prod
=
createProducer
(
xml
,
ClipType
::
Color
,
color
,
name
,
duration
,
QStringLiteral
(
"color"
),
QString
());
QString
id
;
model
->
requestAddBinClip
(
id
,
xml
.
documentElement
(),
parentFolder
,
i18n
(
"Create color clip"
));
return
id
;
bool
res
=
model
->
requestAddBinClip
(
id
,
xml
.
documentElement
(),
parentFolder
,
i18n
(
"Create color clip"
));
return
res
?
id
:
QStringLiteral
(
"-1"
)
;
}
QString
ClipCreator
::
createClipFromFile
(
const
QString
&
path
,
const
QString
&
parentFolder
,
std
::
shared_ptr
<
ProjectItemModel
>
model
,
Fun
&
undo
,
Fun
&
redo
)
{
QDomDocument
xml
;
QUrl
url
(
path
);
QMimeDatabase
db
;
QMimeType
type
=
db
.
mimeTypeForUrl
(
url
);
qDebug
()
<<
"/////////// createClipFromFile"
<<
path
<<
parentFolder
<<
url
<<
type
.
name
();
QDomElement
prod
;
if
(
type
.
name
().
startsWith
(
QLatin1String
(
"image/"
)))
{
int
duration
=
pCore
->
currentDoc
()
->
getFramePos
(
KdenliveSettings
::
image_duration
());
prod
=
createProducer
(
xml
,
ClipType
::
Image
,
path
,
QString
(),
duration
,
QString
(),
QString
());
}
else
if
(
type
.
inherits
(
QStringLiteral
(
"application/x-kdenlivetitle"
)))
{
// opening a title file
QDomDocument
txtdoc
(
QStringLiteral
(
"titledocument"
));
QFile
txtfile
(
url
.
toLocalFile
());
if
(
txtfile
.
open
(
QIODevice
::
ReadOnly
)
&&
txtdoc
.
setContent
(
&
txtfile
))
{
txtfile
.
close
();
// extract embedded images
QDomNodeList
items
=
txtdoc
.
elementsByTagName
(
QStringLiteral
(
"content"
));
for
(
int
j
=
0
;
j
<
items
.
count
();
++
j
)
{
QDomElement
content
=
items
.
item
(
j
).
toElement
();
if
(
content
.
hasAttribute
(
QStringLiteral
(
"base64"
)))
{
QString
titlesFolder
=
pCore
->
currentDoc
()
->
projectDataFolder
()
+
QStringLiteral
(
"/titles/"
);
QString
imgPath
=
TitleDocument
::
extractBase64Image
(
titlesFolder
,
content
.
attribute
(
QStringLiteral
(
"base64"
)));
if
(
!
imgPath
.
isEmpty
())
{
content
.
setAttribute
(
QStringLiteral
(
"url"
),
imgPath
);
content
.
removeAttribute
(
QStringLiteral
(
"base64"
));
}
}
}
prod
.
setAttribute
(
QStringLiteral
(
"in"
),
0
);
int
duration
=
0
;
if
(
txtdoc
.
documentElement
().
hasAttribute
(
QStringLiteral
(
"duration"
)))
{
duration
=
txtdoc
.
documentElement
().
attribute
(
QStringLiteral
(
"duration"
)).
toInt
();
}
else
if
(
txtdoc
.
documentElement
().
hasAttribute
(
QStringLiteral
(
"out"
)))
{
duration
=
txtdoc
.
documentElement
().
attribute
(
QStringLiteral
(
"out"
)).
toInt
();
}
if
(
duration
<=
0
)
{
duration
=
pCore
->
currentDoc
()
->
getFramePos
(
KdenliveSettings
::
title_duration
())
-
1
;
}
prod
=
createProducer
(
xml
,
ClipType
::
Text
,
path
,
QString
(),
duration
,
QString
(),
QString
());
txtdoc
.
documentElement
().
setAttribute
(
QStringLiteral
(
"duration"
),
duration
);
QString
titleData
=
txtdoc
.
toString
();
prod
.
setAttribute
(
QStringLiteral
(
"xmldata"
),
titleData
);
}
else
{
txtfile
.
close
();
return
QStringLiteral
(
"-1"
);
}
}
else
{
// it is a "normal" file, just use a producer
prod
=
xml
.
createElement
(
QStringLiteral
(
"producer"
));
xml
.
appendChild
(
prod
);
QMap
<
QString
,
QString
>
properties
;
properties
.
insert
(
QStringLiteral
(
"resource"
),
path
);
Xml
::
addXmlProperties
(
prod
,
properties
);
qDebug
()
<<
"/////////// normal"
<<
url
.
toLocalFile
()
<<
properties
<<
url
;
}
qDebug
()
<<
"/////////// final xml"
<<
xml
.
toString
();
QString
id
;
bool
res
=
model
->
requestAddBinClip
(
id
,
xml
.
documentElement
(),
parentFolder
,
undo
,
redo
);
return
res
?
id
:
QStringLiteral
(
"-1"
);
}