Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Kdenlive
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
261
Issues
261
List
Boards
Labels
Service Desk
Milestones
Merge Requests
16
Merge Requests
16
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Multimedia
Kdenlive
Commits
db7214d9
Commit
db7214d9
authored
Jan 03, 2015
by
Jean-Baptiste Mardelle
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix producer replacement when we want to reload a clip or enable/disable proxy
parent
0fe8482f
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
427 additions
and
110 deletions
+427
-110
src/bin/abstractprojectitem.cpp
src/bin/abstractprojectitem.cpp
+8
-0
src/bin/abstractprojectitem.h
src/bin/abstractprojectitem.h
+11
-1
src/bin/bin.cpp
src/bin/bin.cpp
+39
-19
src/bin/bin.h
src/bin/bin.h
+15
-1
src/bin/projectclip.cpp
src/bin/projectclip.cpp
+18
-30
src/bin/projectclip.h
src/bin/projectclip.h
+2
-6
src/bin/projectfolder.cpp
src/bin/projectfolder.cpp
+1
-0
src/dialogs/clipcreationdialog.cpp
src/dialogs/clipcreationdialog.cpp
+104
-0
src/dialogs/clipcreationdialog.h
src/dialogs/clipcreationdialog.h
+1
-0
src/doc/kdenlivedoc.cpp
src/doc/kdenlivedoc.cpp
+75
-2
src/doc/kdenlivedoc.h
src/doc/kdenlivedoc.h
+14
-1
src/mltcontroller/bincontroller.cpp
src/mltcontroller/bincontroller.cpp
+39
-5
src/mltcontroller/bincontroller.h
src/mltcontroller/bincontroller.h
+7
-0
src/mltcontroller/clipcontroller.cpp
src/mltcontroller/clipcontroller.cpp
+43
-13
src/mltcontroller/clipcontroller.h
src/mltcontroller/clipcontroller.h
+8
-2
src/project/clipmanager.cpp
src/project/clipmanager.cpp
+3
-4
src/project/jobs/jobmanager.cpp
src/project/jobs/jobmanager.cpp
+1
-1
src/renderer.cpp
src/renderer.cpp
+34
-21
src/timeline/customtrackview.cpp
src/timeline/customtrackview.cpp
+4
-4
No files found.
src/bin/abstractprojectitem.cpp
View file @
db7214d9
...
...
@@ -186,6 +186,9 @@ QVariant AbstractProjectItem::data(DataType type) const
case
JobMessage
:
data
=
QVariant
(
m_jobMessage
);
break
;
case
ClipStatus
:
data
=
QVariant
(
m_clipStatus
);
break
;
default:
break
;
}
...
...
@@ -241,3 +244,8 @@ QPoint AbstractProjectItem::zone() const
return
QPoint
();
}
void
AbstractProjectItem
::
setClipStatus
(
CLIPSTATUS
status
)
{
m_clipStatus
=
status
;
}
src/bin/abstractprojectitem.h
View file @
db7214d9
...
...
@@ -27,7 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QObject>
#include <QPixmap>
#include <QUrl>
class
ProjectClip
;
...
...
@@ -126,7 +125,16 @@ public:
JobType
=
Qt
::
UserRole
+
1
,
JobProgress
,
JobMessage
,
ClipStatus
};
enum
CLIPSTATUS
{
StatusReady
=
0
,
StatusMissing
,
StatusWaiting
};
void
setClipStatus
(
AbstractProjectItem
::
CLIPSTATUS
status
);
/** @brief Returns the data that describes this item.
* @param type type of data to return
...
...
@@ -170,8 +178,10 @@ protected:
QString
m_duration
;
QPoint
m_zone
;
QString
m_id
;
CLIPSTATUS
m_clipStatus
;
AbstractClipJob
::
JOBTYPE
m_jobType
;
int
m_jobProgress
;
QString
m_jobMessage
;
PROJECTITEMTYPE
m_itemType
;
...
...
src/bin/bin.cpp
View file @
db7214d9
...
...
@@ -232,7 +232,7 @@ void Bin::slotAddClip()
{
// Check if we are in a folder
QStringList
folderInfo
=
getFolderInfo
();
pCore
->
projectManager
()
->
current
()
->
clipManager
()
->
slotAddClip
(
QString
(),
folderInfo
);
ClipCreationDialogDialog
::
createClipsCommand
(
pCore
->
projectManager
()
->
current
(),
folderInfo
,
this
);
}
void
Bin
::
deleteClip
(
const
QString
&
id
)
...
...
@@ -264,13 +264,19 @@ void Bin::slotDeleteClip()
void
Bin
::
slotReloadClip
()
{
QModelIndex
ix
=
m_proxyModel
->
selectionModel
()
->
currentIndex
();
if
(
ix
.
isValid
()
&&
m_proxyModel
->
selectionModel
()
->
isSelected
(
ix
))
{
AbstractProjectItem
*
currentItem
=
static_cast
<
AbstractProjectItem
*>
(
ix
.
internalPointer
());
QModelIndexList
indexes
=
m_proxyModel
->
selectionModel
()
->
selectedIndexes
();
foreach
(
const
QModelIndex
&
ix
,
indexes
)
{
if
(
!
ix
.
isValid
())
{
continue
;
}
AbstractProjectItem
*
currentItem
=
static_cast
<
AbstractProjectItem
*>
(
m_proxyModel
->
mapToSource
(
ix
).
internalPointer
());
if
(
currentItem
&&
!
currentItem
->
isFolder
())
{
reloadClip
(
currentItem
->
clipId
()
);
m_monitor
->
openClip
(
NULL
);
QDomDocument
doc
;
QDomElement
xml
=
currentItem
->
toXml
(
doc
);
currentItem
->
setClipStatus
(
AbstractProjectItem
::
StatusWaiting
);
// We need to set a temporary id before all outdated producers are replaced;
pCore
->
projectManager
()
->
current
()
->
renderer
()
->
getFileProperties
(
xml
,
currentItem
->
clipId
(),
150
,
true
);
}
}
...
...
@@ -670,12 +676,11 @@ void Bin::showClipProperties(ProjectClip *clip)
void
Bin
::
reloadClip
(
const
QString
&
id
)
{
/*pCore->projectManager()->current()->binMonitor()->prepareReload(id);
pCore->projectManager()->current()->bin()->reloadClip(id);
if (m_propertiesPanel && m_propertiesPanel->property("clipId").toString() == id) {
m_editedProducer->setProducer(pCore->projectManager()->current()->bin()->clipProducer(id));
}
pCore->projectManager()->current()->binMonitor()->open(pCore->projectManager()->current()->bin()->clipProducer(id));*/
ProjectClip
*
clip
=
m_rootFolder
->
clip
(
id
);
if
(
!
clip
)
return
;
QDomDocument
doc
;
QDomElement
xml
=
clip
->
toXml
(
doc
);
pCore
->
projectManager
()
->
current
()
->
renderer
()
->
getFileProperties
(
xml
,
id
,
150
,
true
);
}
void
Bin
::
refreshEditedClip
()
...
...
@@ -703,12 +708,24 @@ ProjectClip *Bin::getBinClip(const QString &id)
return
clip
;
}
void
Bin
::
setWaitingStatus
(
const
QString
&
id
)
{
ProjectClip
*
clip
=
m_rootFolder
->
clip
(
id
);
if
(
clip
)
clip
->
setClipStatus
(
AbstractProjectItem
::
StatusWaiting
);
}
void
Bin
::
slotProducerReady
(
requestClipInfo
info
,
ClipController
*
controller
)
{
ProjectClip
*
clip
=
m_rootFolder
->
clip
(
info
.
clipId
);
if
(
clip
)
{
clip
->
setProducer
(
controller
,
info
.
replaceProducer
);
emit
producerReady
(
info
.
clipId
);
if
(
!
clip
->
hasProxy
())
{
// Check for file modifications
ClipType
t
=
clip
->
clipType
();
if
(
t
==
AV
||
t
==
Audio
||
t
==
Image
||
t
==
Video
||
t
==
Playlist
)
{
m_doc
->
watchFile
(
clip
->
url
());
}
}
if
(
controller
)
clip
->
setProducer
(
controller
,
info
.
replaceProducer
);
QString
currentClip
=
m_monitor
->
activeClipId
();
if
(
currentClip
.
isEmpty
())
{
//No clip displayed in monitor, check if item is selected
...
...
@@ -717,13 +734,15 @@ void Bin::slotProducerReady(requestClipInfo info, ClipController *controller)
ProjectClip
*
currentItem
=
static_cast
<
ProjectClip
*>
(
m_proxyModel
->
mapToSource
(
ix
).
internalPointer
());
if
(
currentItem
->
clipId
()
==
info
.
clipId
)
{
// Item was selected, show it in monitor
m_monitor
->
openClip
(
controller
);
currentItem
->
setCurrent
(
true
);
break
;
}
}
}
else
if
(
currentClip
==
info
.
clipId
)
{
m_monitor
->
openClip
(
controller
);
m_monitor
->
openClip
(
NULL
);
clip
->
setCurrent
(
true
);
//m_monitor->openClip(controller);
}
}
else
{
...
...
@@ -743,6 +762,7 @@ void Bin::slotProducerReady(requestClipInfo info, ClipController *controller)
ProjectClip
*
newItem
=
new
ProjectClip
(
info
.
clipId
,
controller
,
parentFolder
);
if
(
info
.
clipId
.
toInt
()
>=
m_clipCounter
)
m_clipCounter
=
info
.
clipId
.
toInt
()
+
1
;
}
emit
producerReady
(
info
.
clipId
);
}
void
Bin
::
openProducer
(
ClipController
*
controller
)
...
...
@@ -814,7 +834,7 @@ JobManager *Bin::jobManager()
void
Bin
::
updateJobStatus
(
const
QString
&
id
,
int
jobType
,
int
status
,
const
QString
&
label
,
const
QString
&
actionName
,
const
QString
&
details
)
{
ProjectClip
*
clip
=
getBinC
lip
(
id
);
ProjectClip
*
clip
=
m_rootFolder
->
c
lip
(
id
);
if
(
clip
)
{
clip
->
setJobStatus
((
AbstractClipJob
::
JOBTYPE
)
jobType
,
(
ClipJobStatus
)
status
);
}
...
...
@@ -822,7 +842,7 @@ void Bin::updateJobStatus(const QString&id, int jobType, int status, const QStri
void
Bin
::
gotProxy
(
const
QString
&
id
)
{
ProjectClip
*
clip
=
getBinC
lip
(
id
);
ProjectClip
*
clip
=
m_rootFolder
->
c
lip
(
id
);
if
(
clip
)
{
QDomDocument
doc
;
QDomElement
xml
=
clip
->
toXml
(
doc
);
...
...
@@ -888,7 +908,7 @@ void Bin::slotItemDropped(QStringList ids, const QModelIndex &parent)
parentItem
=
m_rootFolder
;
}
foreach
(
const
QString
&
id
,
ids
)
{
ProjectClip
*
currentItem
=
getBinC
lip
(
id
);
ProjectClip
*
currentItem
=
m_rootFolder
->
c
lip
(
id
);
AbstractProjectItem
*
currentParent
=
currentItem
->
parent
();
if
(
currentParent
!=
parentItem
)
{
// Item was dropped on a different folder
...
...
@@ -902,6 +922,7 @@ void Bin::slotItemDropped(const QList<QUrl>&urls, const QModelIndex &parent)
{
QStringList
folderInfo
;
if
(
parent
.
isValid
())
{
// Check if drop occured on a folder
AbstractProjectItem
*
parentItem
=
static_cast
<
AbstractProjectItem
*>
(
parent
.
internalPointer
());
while
(
!
parentItem
->
isFolder
())
{
parentItem
=
parentItem
->
parent
();
...
...
@@ -915,4 +936,3 @@ void Bin::slotItemDropped(const QList<QUrl>&urls, const QModelIndex &parent)
ClipCreationDialogDialog
::
createClipsCommand
(
pCore
->
projectManager
()
->
current
(),
urls
,
folderInfo
,
this
);
}
src/bin/bin.h
View file @
db7214d9
...
...
@@ -98,6 +98,15 @@ public:
// Draw thumbnail
opt
.
icon
.
paint
(
painter
,
r
);
// Overlay icon if necessary
/* WIP
int clipStatus = index.data(AbstractProjectItem::ClipStatus).toInt();
if (clipStatus == (int) AbstractProjectItem::StatusWaiting) {
QIcon reload = QIcon::fromTheme("media-playback-pause");
reload.paint(painter, r);
}
*/
int
decoWidth
=
r
.
width
()
+
2
*
textMargin
;
QFont
font
=
painter
->
font
();
...
...
@@ -255,6 +264,9 @@ public:
void
emitAboutToRemoveItem
(
AbstractProjectItem
*
item
);
void
emitItemRemoved
(
AbstractProjectItem
*
item
);
void
setupMenu
(
QMenu
*
addMenu
,
QAction
*
defaultAction
);
/** @brief The source file was modified, we will reload it soon, disable item in the meantime */
void
setWaitingStatus
(
const
QString
&
id
);
/** @brief Update status for clip jobs */
void
updateJobStatus
(
const
QString
&
,
int
,
int
,
const
QString
&
label
=
QString
(),
const
QString
&
actionName
=
QString
(),
const
QString
&
details
=
QString
());
...
...
@@ -277,6 +289,9 @@ public:
/** @brief Returns the id of the last inserted clip */
int
lastClipId
()
const
;
/** @brief Ask MLT to reload this clip's producer */
void
reloadClip
(
const
QString
&
id
);
/** @brief Defines the values for data roles */
enum
DATATYPE
{
...
...
@@ -302,7 +317,6 @@ private slots:
void
closeEditing
();
void
refreshEditedClip
();
void
slotMarkersNeedUpdate
(
const
QString
&
id
,
const
QList
<
int
>
&
markers
);
void
reloadClip
(
const
QString
&
id
);
void
slotSaveHeaders
();
void
slotItemDropped
(
QStringList
ids
,
const
QModelIndex
&
parent
);
void
slotItemDropped
(
const
QList
<
QUrl
>&
urls
,
const
QModelIndex
&
parent
);
...
...
src/bin/projectclip.cpp
View file @
db7214d9
...
...
@@ -40,10 +40,9 @@ ProjectClip::ProjectClip(const QString &id, ClipController *controller, ProjectF
,
audioFrameCache
()
,
m_audioThumbCreated
(
false
)
{
m_
properties
=
QMap
<
QString
,
QString
>
()
;
m_
clipStatus
=
StatusReady
;
m_name
=
m_controller
->
clipName
();
m_duration
=
m_controller
->
getStringDuration
();
getFileHash
();
setParent
(
parent
);
}
...
...
@@ -55,7 +54,7 @@ ProjectClip::ProjectClip(const QDomElement& description, ProjectFolder* parent)
,
m_audioThumbCreated
(
false
)
{
Q_ASSERT
(
description
.
hasAttribute
(
"id"
));
m_
properties
=
QMap
<
QString
,
QString
>
()
;
m_
clipStatus
=
StatusWaiting
;
QString
resource
=
getXmlProperty
(
description
,
"resource"
);
if
(
!
resource
.
isEmpty
())
{
m_name
=
QUrl
::
fromLocalFile
(
resource
).
fileName
();
...
...
@@ -69,7 +68,7 @@ ProjectClip::ProjectClip(const QDomElement& description, ProjectFolder* parent)
ProjectClip
::~
ProjectClip
()
{
delete
m_controller
;
// controller is deleted in bincontroller
}
QString
ProjectClip
::
getXmlProperty
(
const
QDomElement
&
producer
,
const
QString
&
propertyName
)
...
...
@@ -170,7 +169,7 @@ void ProjectClip::reloadProducer()
{
QDomDocument
doc
;
QDomElement
xml
=
toXml
(
doc
);
bin
()
->
reloadProducer
(
m_id
,
doc
.
documentElement
()
);
bin
()
->
reloadProducer
(
m_id
,
xml
);
}
void
ProjectClip
::
setCurrent
(
bool
current
,
bool
notify
)
...
...
@@ -183,20 +182,11 @@ void ProjectClip::setCurrent(bool current, bool notify)
QDomElement
ProjectClip
::
toXml
(
QDomDocument
&
document
)
{
QDomElement
prod
=
document
.
createElement
(
"producer"
);
document
.
appendChild
(
prod
);
QDomElement
prop
=
document
.
createElement
(
"property"
);
prop
.
setAttribute
(
"name"
,
"resource"
);
QString
path
=
m_properties
.
value
(
"proxy"
);
if
(
path
.
length
()
<
2
)
{
// No proxy
path
=
m_controller
->
clipUrl
().
toLocalFile
();
if
(
m_controller
)
{
m_controller
->
getProducerXML
(
document
);
return
document
.
documentElement
().
firstChildElement
(
"producer"
);
}
QDomText
value
=
document
.
createTextNode
(
path
);
prop
.
appendChild
(
value
);
prod
.
appendChild
(
prop
);
prod
.
setAttribute
(
"id"
,
m_id
);
return
prod
;
return
QDomElement
();
}
QPixmap
ProjectClip
::
thumbnail
(
bool
force
)
...
...
@@ -237,7 +227,7 @@ void ProjectClip::setProducer(ClipController *controller, bool replaceProducer)
}
if
(
m_controller
)
{
// Replace clip for this controller
m_controller
->
updateProducer
(
controller
->
masterProducer
(
));
//m_controller->updateProducer(m_id, &(controller->originalProducer()
));
delete
controller
;
}
else
{
...
...
@@ -246,6 +236,7 @@ void ProjectClip::setProducer(ClipController *controller, bool replaceProducer)
if
(
m_name
.
isEmpty
())
m_name
=
m_controller
->
clipName
();
m_duration
=
m_controller
->
getStringDuration
();
}
m_clipStatus
=
StatusReady
;
bin
()
->
emitItemUpdated
(
this
);
getFileHash
();
}
...
...
@@ -380,14 +371,9 @@ const QString ProjectClip::getFileHash() const
return
QString
();
}
const
QString
ProjectClip
::
getProperty
(
const
QString
&
key
)
const
{
return
m_properties
.
value
(
key
);
}
bool
ProjectClip
::
hasProxy
()
const
{
QString
proxy
=
m_properties
.
value
(
"proxy"
);
QString
proxy
=
getProducerProperty
(
"proxy"
);
if
(
proxy
.
isEmpty
()
||
proxy
==
"-"
)
return
false
;
return
true
;
}
...
...
@@ -398,15 +384,12 @@ void ProjectClip::setProperties(QMap <QString, QString> properties)
bool
refreshProducer
=
false
;
QStringList
keys
;
keys
<<
"luma_duration"
<<
"luma_file"
<<
"fade"
<<
"ttl"
<<
"softness"
<<
"crop"
<<
"animation"
;
QString
oldProxy
=
m_properties
.
value
(
"proxy"
);
while
(
i
.
hasNext
())
{
i
.
next
();
setProducerProperty
(
i
.
key
().
toUtf8
().
data
(),
i
.
value
().
toUtf8
().
data
());
m_properties
.
insert
(
i
.
key
(),
i
.
value
());
if
(
clipType
()
==
SlideShow
&&
keys
.
contains
(
i
.
key
()))
refreshProducer
=
true
;
}
if
(
properties
.
contains
(
"proxy"
))
{
qDebug
()
<<
"/// CLIP UPDATE, ASK PROXY"
;
QString
value
=
properties
.
value
(
"proxy"
);
// If value is "-", that means user manually disabled proxy on this clip
if
(
value
.
isEmpty
()
||
value
==
"-"
)
{
...
...
@@ -414,10 +397,14 @@ void ProjectClip::setProperties(QMap <QString, QString> properties)
if
(
bin
()
->
hasPendingJob
(
m_id
,
AbstractClipJob
::
PROXYJOB
))
{
bin
()
->
discardJobs
(
m_id
,
AbstractClipJob
::
PROXYJOB
);
}
else
reloadProducer
();
else
{
reloadProducer
();
}
}
else
{
bin
()
->
startJob
(
m_id
,
AbstractClipJob
::
PROXYJOB
);
// A proxy was requested, make sure to keep original url
setProducerProperty
(
"kdenlive_originalUrl"
,
url
().
toLocalFile
().
toUtf8
().
data
());
bin
()
->
startJob
(
m_id
,
AbstractClipJob
::
PROXYJOB
);
}
}
//if (refreshProducer) slotRefreshProducer();
...
...
@@ -437,3 +424,4 @@ void ProjectClip::setJobStatus(AbstractClipJob::JOBTYPE jobType, ClipJobStatus s
}
bin
()
->
emitItemUpdated
(
this
);
}
src/bin/projectclip.h
View file @
db7214d9
...
...
@@ -136,9 +136,6 @@ public:
/** @brief Set properties on this clip. TODO: should we store all in MLT or use extra m_properties ?. */
void
setProperties
(
QMap
<
QString
,
QString
>
properties
);
/** @brief Get a property stored in m_properties. */
const
QString
getProperty
(
const
QString
&
key
)
const
;
/** @brief Get an XML property from MLT produced xml. */
static
QString
getXmlProperty
(
const
QDomElement
&
producer
,
const
QString
&
propertyName
);
...
...
@@ -165,6 +162,8 @@ public:
/** format is frame -> channel ->bytes */
QMap
<
int
,
QMap
<
int
,
QByteArray
>
>
audioFrameCache
;
bool
audioThumbCreated
()
const
;
void
setWaitingStatus
(
const
QString
&
id
);
public
slots
:
//TODO
...
...
@@ -172,14 +171,11 @@ public slots:
void
updateAudioThumbnail
(
const
audioByteArray
&
data
);
protected:
QUrl
m_url
;
bool
m_hasLimitedDuration
;
private:
//TODO: clip markers
QList
<
int
>
m_markers
;
//TODO: handle properties inside MLT ?
QMap
<
QString
,
QString
>
m_properties
;
/** @brief The Clip controller for this clip. */
ClipController
*
m_controller
;
/** @brief Generate and store file hash if not available. */
...
...
src/bin/projectfolder.cpp
View file @
db7214d9
...
...
@@ -33,6 +33,7 @@ ProjectFolder::ProjectFolder(const QString &id, const QString &name, ProjectFold
{
//loadChildren(description);
m_name
=
name
;
m_clipStatus
=
StatusReady
;
m_thumbnail
=
QIcon
::
fromTheme
(
"folder"
).
pixmap
(
40
,
40
);
setParent
(
parent
);
}
...
...
src/dialogs/clipcreationdialog.cpp
View file @
db7214d9
...
...
@@ -30,7 +30,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "project/dialogs/slideshowclip.h"
#include <KMessageBox>
#include <KRecentDirs>
#include "klocalizedstring.h"
#include <QDir>
#include <QUndoStack>
#include <QUndoCommand>
...
...
@@ -149,6 +151,27 @@ void ClipCreationDialogDialog::createTitleClip(KdenliveDoc *doc, QStringList gro
void
ClipCreationDialogDialog
::
createClipsCommand
(
KdenliveDoc
*
doc
,
const
QList
<
QUrl
>
&
urls
,
QStringList
groupInfo
,
Bin
*
bin
)
{
QUndoCommand
*
addClips
=
new
QUndoCommand
();
//TODO check folders
/*QList < QList<QUrl> > foldersList;
QMimeDatabase db;
foreach(const QUrl & file, list) {
// Check there is no folder here
QMimeType type = db.mimeTypeForUrl(file);
if (type.inherits("inode/directory")) {
// user dropped a folder, import its files
list.removeAll(file);
QDir dir(file.path());
QStringList result = dir.entryList(QDir::Files);
QList <QUrl> folderFiles;
folderFiles << file;
foreach(const QString & path, result) {
folderFiles.append(QUrl::fromLocalFile(dir.absoluteFilePath(path)));
}
if (folderFiles.count() > 1) foldersList.append(folderFiles);
}
}*/
foreach
(
const
QUrl
&
file
,
urls
)
{
QDomDocument
xml
;
QDomElement
prod
=
xml
.
createElement
(
"producer"
);
...
...
@@ -234,3 +257,84 @@ void ClipCreationDialogDialog::createClipsCommand(KdenliveDoc *doc, const QList<
doc
->
commandStack
()
->
push
(
addClips
);
}
}
void
ClipCreationDialogDialog
::
createClipsCommand
(
KdenliveDoc
*
doc
,
QStringList
groupInfo
,
Bin
*
bin
)
{
QList
<
QUrl
>
list
;
QString
allExtensions
=
"*"
;
//getExtensions().join(" ");
const
QString
dialogFilter
=
i18n
(
"All Supported Files"
)
+
"("
+
allExtensions
+
");;"
+
i18n
(
"All Files"
)
+
"(*)"
;
QCheckBox
*
b
=
new
QCheckBox
(
i18n
(
"Import image sequence"
));
b
->
setChecked
(
KdenliveSettings
::
autoimagesequence
());
QCheckBox
*
c
=
new
QCheckBox
(
i18n
(
"Transparent background for images"
));
c
->
setChecked
(
KdenliveSettings
::
autoimagetransparency
());
QFrame
*
f
=
new
QFrame
();
f
->
setFrameShape
(
QFrame
::
NoFrame
);
QHBoxLayout
*
l
=
new
QHBoxLayout
;
l
->
addWidget
(
b
);
l
->
addWidget
(
c
);
l
->
addStretch
(
5
);
f
->
setLayout
(
l
);
QString
clipFolder
=
KRecentDirs
::
dir
(
":KdenliveClipFolder"
);
if
(
clipFolder
.
isEmpty
())
{
clipFolder
=
QDir
::
homePath
();
}
QPointer
<
QFileDialog
>
d
=
new
QFileDialog
(
QApplication
::
activeWindow
(),
i18n
(
"Open Clips"
),
clipFolder
,
dialogFilter
);
//TODO: KF5, how to add a custom widget to file dialog
/*QGridLayout *layout = (QGridLayout*)d->layout();
layout->addWidget(f, 0, 0);*/
d
->
setFileMode
(
QFileDialog
::
ExistingFiles
);
if
(
d
->
exec
()
==
QDialog
::
Accepted
)
{
KdenliveSettings
::
setAutoimagetransparency
(
c
->
isChecked
());
list
=
d
->
selectedUrls
();
if
(
!
list
.
isEmpty
())
{
KRecentDirs
::
add
(
":KdenliveClipFolder"
,
list
.
first
().
adjusted
(
QUrl
::
RemoveFilename
).
path
());
}
if
(
b
->
isChecked
()
&&
list
.
count
()
==
1
)
{
// Check for image sequence
QUrl
url
=
list
.
at
(
0
);
QString
fileName
=
url
.
fileName
().
section
(
'.'
,
0
,
-
2
);
if
(
fileName
.
at
(
fileName
.
size
()
-
1
).
isDigit
())
{
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
);
int
count
=
list
.
count
();
if
(
count
>
1
)
{
delete
d
;
/*QStringList groupInfo = getGroup(); */
// get image sequence base name
while
(
fileName
.
at
(
fileName
.
size
()
-
1
).
isDigit
())
{
fileName
.
chop
(
1
);
}
QDomDocument
xml
;
QDomElement
prod
=
xml
.
createElement
(
"producer"
);
xml
.
appendChild
(
prod
);
prod
.
setAttribute
(
"name"
,
fileName
);
prod
.
setAttribute
(
"resource"
,
pattern
);
prod
.
setAttribute
(
"in"
,
"0"
);
QString
duration
=
doc
->
timecode
().
reformatSeparators
(
KdenliveSettings
::
sequence_duration
());
prod
.
setAttribute
(
"out"
,
QString
::
number
(
doc
->
getFramePos
(
duration
)
*
count
));
prod
.
setAttribute
(
"ttl"
,
QString
::
number
(
doc
->
getFramePos
(
duration
)));
prod
.
setAttribute
(
"loop"
,
QString
::
number
(
false
));
prod
.
setAttribute
(
"crop"
,
QString
::
number
(
false
));
prod
.
setAttribute
(
"fade"
,
QString
::
number
(
false
));
prod
.
setAttribute
(
"luma_duration"
,
QString
::
number
(
doc
->
getFramePos
(
doc
->
timecode
().
getTimecodeFromFrames
(
int
(
ceil
(
doc
->
timecode
().
fps
()))))));
if
(
!
groupInfo
.
isEmpty
())
{
prod
.
setAttribute
(
"group"
,
groupInfo
.
at
(
0
));
prod
.
setAttribute
(
"groupid"
,
groupInfo
.
at
(
1
));
}
uint
id
=
bin
->
getFreeClipId
();
AddClipCommand
*
command
=
new
AddClipCommand
(
doc
,
xml
.
documentElement
(),
QString
::
number
(
id
),
true
);
doc
->
commandStack
()
->
push
(
command
);
return
;
}
}
}
}
}
delete
d
;
if
(
!
list
.
isEmpty
())
{
ClipCreationDialogDialog
::
createClipsCommand
(
doc
,
list
,
groupInfo
,
bin
);
}
}
\ No newline at end of file
src/dialogs/clipcreationdialog.h
View file @
db7214d9
...
...
@@ -43,6 +43,7 @@ public:
static
void
createSlideshowClip
(
KdenliveDoc
*
doc
,
QStringList
groupInfo
,
Bin
*
bin
);
static
void
createTitleClip
(
KdenliveDoc
*
doc
,
QStringList
groupInfo
,
QString
templatePath
,
Bin
*
bin
);
static
void
createClipsCommand
(
KdenliveDoc
*
doc
,
const
QList
<
QUrl
>
&
urls
,
QStringList
groupInfo
,
Bin
*
bin
);
static
void
createClipsCommand
(
KdenliveDoc
*
doc
,
QStringList
groupInfo
,
Bin
*
bin
);
};
...
...
src/doc/kdenlivedoc.cpp
View file @
db7214d9
...
...
@@ -96,6 +96,13 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QUrl &projectFolder, QUndoGroup
connect
(
m_clipManager
,
SIGNAL
(
displayMessage
(
QString
,
int
)),
parent
,
SLOT
(
slotGotProgressInfo
(
QString
,
int
)));
bool
success
=
false
;
// Init clip modification tracker
m_modifiedTimer
.
setInterval
(
1500
);
connect
(
&
m_fileWatcher
,
&
KDirWatch
::
dirty
,
this
,
&
KdenliveDoc
::
slotClipModified
);
connect
(
&
m_fileWatcher
,
&
KDirWatch
::
deleted
,
this
,
&
KdenliveDoc
::
slotClipMissing
);
connect
(
&
m_modifiedTimer
,
&
QTimer
::
timeout
,
this
,
&
KdenliveDoc
::
slotProcessModifiedClips
);
// init default document properties
m_documentProperties
[
"zoom"
]
=
'7'
;
m_documentProperties
[
"verticalzoom"
]
=
'1'
;
...
...
@@ -1273,8 +1280,16 @@ bool KdenliveDoc::addClipInfo(QDomElement elem, QDomElement orig, const QString
void
KdenliveDoc
::
deleteClip
(
const
QString
&
clipId
)
{
//emit signalDeleteProjectClip(clipId);
qDebug
()
<<
"++++++++++++++++++++++++++++
\n
DELETING CLIP ID: "
<<
clipId
;
m_clipManager
->
deleteClip
(
clipId
);
ClipController
*
controller
=
pCore
->
binController
()
->
getController
(
clipId
);
ClipType
type
=
controller
->
clipType
();
QString
url
=
controller
->
clipUrl
().
toLocalFile
();
if
(
type
!=
Color
&&
type
!=
SlideShow
&&
!
url
.
isEmpty
())
{
m_fileWatcher
.
removeFile
(
url
);
}
// Delete clip in bin
pCore
->
bin
()
->
deleteClip
(
clipId
);
// Delete controller and Mlt::Producer
pCore
->
binController
()
->
removeBinClip
(
clipId
);
}
void
KdenliveDoc
::
addClipList
(
const
QList
<
QUrl
>
&
urls
,
const
QMap
<
QString
,
QString
>
&
data
)
...
...
@@ -1913,3 +1928,61 @@ void KdenliveDoc::slotUpdateClipProperties(const QString &id, QMap <QString, QSt
}
}
//TODO put all file watching stuff in own class
void
KdenliveDoc
::
watchFile
(
const
QUrl
&
url
)
{
m_fileWatcher
.
addFile
(
url
.
toLocalFile
());
}
void
KdenliveDoc
::
slotClipModified
(
const
QString
&
path
)
{
qDebug
()
<<
"// CLIP: "
<<
path
<<
" WAS MODIFIED"
;
QStringList
ids
=
pCore
->
binController
()
->
getBinIdsByResource
(
QUrl
::
fromLocalFile
(
path
));
foreach
(
const
QString
&
id
,
ids
)
{
if
(
!
m_modifiedClips
.
contains
(
id
))
{
pCore
->
bin
()
->
setWaitingStatus
(
id
);
}
m_modifiedClips
[
id
]
=
QTime
::
currentTime
();
}
if
(
!
m_modifiedTimer
.
isActive
())
m_modifiedTimer
.
start
();
}
void
KdenliveDoc
::
slotClipMissing
(
const
QString
&
path
)
{
qDebug
()
<<
"// CLIP: "
<<
path
<<
" WAS MISSING"
;
QStringList
ids
=
pCore
->
binController
()
->
getBinIdsByResource
(
QUrl
::
fromLocalFile
(
path
));
foreach
(
const
QString
&
id
,
ids
)
{
//TODO handle missing clips by replacing producer with an invalid producer
//emit missingClip(id);
}
}
void
KdenliveDoc
::
slotClipAvailable
(
const
QString
&
path
)