Skip to content
GitLab
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
9eadd8fe
Commit
9eadd8fe
authored
Feb 08, 2015
by
Jean-Baptiste Mardelle
Browse files
Load / save timeline guides
parent
7aae9051
Changes
15
Hide whitespace changes
Inline
Side-by-side
src/core.cpp
View file @
9eadd8fe
...
...
@@ -11,6 +11,7 @@ the Free Software Foundation, either version 3 of the License, or
#include
"core.h"
#include
"mainwindow.h"
#include
"project/projectmanager.h"
#include
"timeline/trackview.h"
#include
"monitor/monitormanager.h"
#include
"mltcontroller/bincontroller.h"
#include
"bin/bin.h"
...
...
src/dialogs/renderwidget.cpp
View file @
9eadd8fe
...
...
@@ -378,12 +378,11 @@ void RenderWidget::slotCheckEndGuidePosition()
m_view
.
guide_end
->
setCurrentIndex
(
m_view
.
guide_start
->
currentIndex
());
}
void
RenderWidget
::
setGuides
(
Q
DomElement
guides
xml
,
double
duration
)
void
RenderWidget
::
setGuides
(
Q
Map
<
double
,
QString
>
guides
Data
,
double
duration
)
{
m_view
.
guide_start
->
clear
();
m_view
.
guide_end
->
clear
();
QDomNodeList
nodes
=
guidesxml
.
elementsByTagName
(
"guide"
);
if
(
!
nodes
.
isEmpty
())
{
if
(
!
guidesData
.
isEmpty
())
{
m_view
.
guide_start
->
addItem
(
i18n
(
"Beginning"
),
"0"
);
m_view
.
render_guide
->
setEnabled
(
true
);
m_view
.
create_chapter
->
setEnabled
(
true
);
...
...
@@ -392,16 +391,15 @@ void RenderWidget::setGuides(QDomElement guidesxml, double duration)
m_view
.
create_chapter
->
setEnabled
(
false
);
}
double
fps
=
(
double
)
m_profile
.
frame_rate_num
/
m_profile
.
frame_rate_den
;
for
(
int
i
=
0
;
i
<
nodes
.
count
();
++
i
)
{
QDomElement
e
=
nodes
.
item
(
i
).
toElement
();
if
(
!
e
.
isNull
())
{
GenTime
pos
=
GenTime
(
e
.
attribute
(
"time"
).
toDouble
());
const
QString
guidePos
=
Timecode
::
getStringTimecode
(
pos
.
frames
(
fps
),
fps
);
m_view
.
guide_start
->
addItem
(
e
.
attribute
(
"comment"
)
+
'/'
+
guidePos
,
e
.
attribute
(
"time"
).
toDouble
());
m_view
.
guide_end
->
addItem
(
e
.
attribute
(
"comment"
)
+
'/'
+
guidePos
,
e
.
attribute
(
"time"
).
toDouble
());
}
}
if
(
!
nodes
.
isEmpty
())
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
());
}
if
(
!
guidesData
.
isEmpty
())
m_view
.
guide_end
->
addItem
(
i18n
(
"End"
),
QString
::
number
(
duration
));
}
...
...
src/dialogs/renderwidget.h
View file @
9eadd8fe
...
...
@@ -113,7 +113,7 @@ class RenderWidget : public QDialog
public:
explicit
RenderWidget
(
const
QString
&
projectfolder
,
bool
enableProxy
,
const
MltVideoProfile
&
profile
,
QWidget
*
parent
=
0
);
virtual
~
RenderWidget
();
void
setGuides
(
Q
DomElement
guides
xml
,
double
duration
);
void
setGuides
(
Q
Map
<
double
,
QString
>
guides
Data
,
double
duration
);
void
focusFirstVisibleItem
(
const
QString
&
profile
=
QString
());
void
setProfile
(
const
MltVideoProfile
&
profile
);
void
setRenderJob
(
const
QString
&
dest
,
int
progress
=
0
);
...
...
src/doc/documentvalidator.cpp
View file @
9eadd8fe
...
...
@@ -1009,6 +1009,17 @@ bool DocumentValidator::upgrade(double version, const double currentVersion)
main_playlist
.
appendChild
(
prop
);
}
// Move guides
QDomNodeList
guides
=
m_doc
.
elementsByTagName
(
"guide"
);
for
(
int
i
=
0
;
i
<
guides
.
count
();
++
i
)
{
QDomElement
guide
=
guides
.
at
(
i
).
toElement
();
QDomElement
prop
=
m_doc
.
createElement
(
"property"
);
prop
.
setAttribute
(
"name"
,
"kdenlive:guide."
+
guide
.
attribute
(
"time"
));
QDomText
val
=
m_doc
.
createTextNode
(
guide
.
attribute
(
"comment"
));
prop
.
appendChild
(
val
);
main_playlist
.
appendChild
(
prop
);
}
QDomNode
mlt
=
m_doc
.
firstChildElement
(
"mlt"
);
main_playlist
.
setAttribute
(
"id"
,
pCore
->
binController
()
->
binPlaylistId
());
mlt
.
toElement
().
setAttribute
(
"producer"
,
pCore
->
binController
()
->
binPlaylistId
());
...
...
src/doc/kdenlivedoc.cpp
View file @
9eadd8fe
...
...
@@ -91,8 +91,6 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QUrl &projectFolder, QUndoGroup
m_profile
.
colorspace
=
0
;
m_clipManager
=
new
ClipManager
(
this
);
m_autoSaveTimer
=
new
QTimer
(
this
);
m_autoSaveTimer
->
setSingleShot
(
true
);
connect
(
m_clipManager
,
SIGNAL
(
displayMessage
(
QString
,
int
)),
parent
,
SLOT
(
slotGotProgressInfo
(
QString
,
int
)));
bool
success
=
false
;
...
...
@@ -397,18 +395,15 @@ KdenliveDoc::KdenliveDoc(const QUrl &url, const QUrl &projectFolder, QUndoGroup
updateProjectFolderPlacesEntry
();
////qDebug() << "// SETTING SCENE LIST:\n\n" << m_document.toString();
connect
(
m_autoSaveTimer
,
SIGNAL
(
timeout
()),
this
,
SLOT
(
slotAutoSave
()));
connect
(
m_render
,
SIGNAL
(
addClip
(
const
QUrl
&
,
const
QMap
<
QString
,
QString
>&
)),
m_clipManager
,
SLOT
(
slotAddClipFile
(
const
QUrl
&
,
const
QMap
<
QString
,
QString
>&
)));
}
KdenliveDoc
::~
KdenliveDoc
()
{
m_autoSaveTimer
->
stop
();
delete
m_commandStack
;
//qDebug() << "// DEL CLP MAN";
delete
m_clipManager
;
//qDebug() << "// DEL CLP MAN done";
delete
m_autoSaveTimer
;
if
(
m_autosave
)
{
if
(
!
m_autosave
->
fileName
().
isEmpty
())
m_autosave
->
remove
();
delete
m_autosave
;
...
...
@@ -593,36 +588,13 @@ QDomDocument KdenliveDoc::createEmptyDocument(const QList <TrackInfo> &tracks)
return
doc
;
}
void
KdenliveDoc
::
syncGuides
(
const
QList
<
Guide
*>
&
guides
)
{
m_guidesXml
.
clear
();
QDomElement
guideNode
=
m_guidesXml
.
createElement
(
"guides"
);
m_guidesXml
.
appendChild
(
guideNode
);
QDomElement
e
;
for
(
int
i
=
0
;
i
<
guides
.
count
();
++
i
)
{
e
=
m_guidesXml
.
createElement
(
"guide"
);
e
.
setAttribute
(
"time"
,
guides
.
at
(
i
)
->
position
().
ms
()
/
1000
);
e
.
setAttribute
(
"comment"
,
guides
.
at
(
i
)
->
label
());
guideNode
.
appendChild
(
e
);
}
setModified
(
true
);
emit
guidesUpdated
();
}
QDomElement
KdenliveDoc
::
guidesXml
()
const
{
return
m_guidesXml
.
documentElement
();
}
bool
KdenliveDoc
::
useProxy
()
const
{
return
m_documentProperties
.
value
(
"enableproxy"
).
toInt
();
}
void
KdenliveDoc
::
slotAutoSave
()
void
KdenliveDoc
::
slotAutoSave
(
QMap
<
double
,
QString
>
guidesData
)
{
if
(
m_render
&&
m_autosave
)
{
if
(
!
m_autosave
->
isOpen
()
&&
!
m_autosave
->
open
(
QIODevice
::
ReadWrite
))
{
...
...
@@ -630,7 +602,7 @@ void KdenliveDoc::slotAutoSave()
//qDebug() << "ERROR; CANNOT CREATE AUTOSAVE FILE";
}
//qDebug() << "// AUTOSAVE FILE: " << m_autosave->fileName();
saveSceneList
(
m_autosave
->
fileName
(),
m_render
->
sceneList
(),
true
);
saveSceneList
(
m_autosave
->
fileName
(),
m_render
->
sceneList
(),
guidesData
,
true
);
}
}
...
...
@@ -656,7 +628,7 @@ QPoint KdenliveDoc::zone() const
return
QPoint
(
m_documentProperties
.
value
(
"zonein"
).
toInt
(),
m_documentProperties
.
value
(
"zoneout"
).
toInt
());
}
QDomDocument
KdenliveDoc
::
xmlSceneList
(
const
QString
&
scene
)
QDomDocument
KdenliveDoc
::
xmlSceneList
(
const
QString
&
scene
,
QMap
<
double
,
QString
>
guidesData
)
{
QDomDocument
sceneList
;
sceneList
.
setContent
(
scene
,
true
);
...
...
@@ -677,6 +649,31 @@ QDomDocument KdenliveDoc::xmlSceneList(const QString &scene)
}
}
}
QDomNodeList
pls
=
mlt
.
elementsByTagName
(
"playlist"
);
QDomElement
mainPlaylist
;
for
(
int
i
=
0
;
i
<
pls
.
count
();
++
i
)
{
if
(
pls
.
at
(
i
).
toElement
().
attribute
(
"id"
)
==
pCore
->
binController
()
->
binPlaylistId
())
{
mainPlaylist
=
pls
.
at
(
i
).
toElement
();
break
;
}
}
// Append markers
// Append guides
QMapIterator
<
double
,
QString
>
g
(
guidesData
);
QLocale
locale
;
while
(
g
.
hasNext
())
{
g
.
next
();
QString
propertyName
=
"kdenlive:guide."
+
locale
.
toString
(
g
.
key
());
QDomElement
prop
=
sceneList
.
createElement
(
"property"
);
prop
.
setAttribute
(
"name"
,
propertyName
);
QDomText
val
=
sceneList
.
createTextNode
(
g
.
value
());
prop
.
appendChild
(
val
);
mainPlaylist
.
appendChild
(
prop
);
}
QDomElement
addedXml
=
sceneList
.
createElement
(
"kdenlivedoc"
);
mlt
.
appendChild
(
addedXml
);
...
...
@@ -792,9 +789,6 @@ QDomDocument KdenliveDoc::xmlSceneList(const QString &scene)
}
addedXml
.
appendChild
(
markers
);
// Add guides
if
(
!
m_guidesXml
.
isNull
())
addedXml
.
appendChild
(
sceneList
.
importNode
(
m_guidesXml
.
documentElement
(),
true
));
// Add clip groups
addedXml
.
appendChild
(
sceneList
.
importNode
(
m_clipManager
->
groupsXml
(),
true
));
...
...
@@ -802,9 +796,9 @@ QDomDocument KdenliveDoc::xmlSceneList(const QString &scene)
return
sceneList
;
}
bool
KdenliveDoc
::
saveSceneList
(
const
QString
&
path
,
const
QString
&
scene
,
bool
autosave
)
bool
KdenliveDoc
::
saveSceneList
(
const
QString
&
path
,
const
QString
&
scene
,
QMap
<
double
,
QString
>
guidesData
,
bool
autosave
)
{
QDomDocument
sceneList
=
xmlSceneList
(
scene
);
QDomDocument
sceneList
=
xmlSceneList
(
scene
,
guidesData
);
if
(
sceneList
.
isNull
())
{
//Make sure we don't save if scenelist is corrupted
KMessageBox
::
error
(
QApplication
::
activeWindow
(),
i18n
(
"Cannot write to file %1, scene list is corrupted."
,
path
));
...
...
@@ -1079,7 +1073,7 @@ void KdenliveDoc::setModified(bool mod)
{
// fix mantis#3160: The document may have an empty URL if not saved yet, but should have a m_autosave in any case
if
(
m_autosave
&&
mod
&&
KdenliveSettings
::
crashrecovery
())
{
m_autoSaveTimer
->
start
(
3000
);
// will trigger slotAutoSave() in 3 seconds
emit
startAutoSave
();
}
if
(
mod
==
m_modified
)
return
;
m_modified
=
mod
;
...
...
src/doc/kdenlivedoc.h
View file @
9eadd8fe
...
...
@@ -73,8 +73,6 @@ public:
//void setRenderer(Render *render);
QUndoStack
*
commandStack
();
Render
*
renderer
();
QDomDocument
m_guidesXml
;
QDomElement
guidesXml
()
const
;
ClipManager
*
clipManager
();
/** @brief Adds a clip to the project tree.
...
...
@@ -115,15 +113,14 @@ public:
/** @brief Returns the project folder, used to store project files. */
QUrl
projectFolder
()
const
;
void
syncGuides
(
const
QList
<
Guide
*>
&
guides
);
void
setZoom
(
int
horizontal
,
int
vertical
);
QPoint
zoom
()
const
;
double
dar
()
const
;
double
projectDuration
()
const
;
/** @brief Returns the project file xml. */
QDomDocument
xmlSceneList
(
const
QString
&
scene
);
QDomDocument
xmlSceneList
(
const
QString
&
scene
,
QMap
<
double
,
QString
>
guidesData
);
/** @brief Saves the project file xml to a file. */
bool
saveSceneList
(
const
QString
&
path
,
const
QString
&
scene
,
bool
autosave
=
false
);
bool
saveSceneList
(
const
QString
&
path
,
const
QString
&
scene
,
QMap
<
double
,
QString
>
guidesData
,
bool
autosave
=
false
);
int
tracksCount
()
const
;
TrackInfo
trackInfoAt
(
int
ix
)
const
;
void
insertTrack
(
int
ix
,
const
TrackInfo
&
type
);
...
...
@@ -202,7 +199,6 @@ private:
QUndoStack
*
m_commandStack
;
ClipManager
*
m_clipManager
;
MltVideoProfile
m_profile
;
QTimer
*
m_autoSaveTimer
;
QString
m_searchFolder
;
/** @brief Tells whether the current document has been changed after being saved. */
...
...
@@ -248,11 +244,11 @@ public slots:
void
setModified
(
bool
mod
=
true
);
void
checkProjectClips
(
bool
displayRatioChanged
=
false
,
bool
fpsChanged
=
false
);
void
slotProxyCurrentItem
(
bool
doProxy
);
private
slots
:
/** @brief Saves the current project at the autosave location.
* @description The autosave files are in ~/.kde/data/stalefiles/kdenlive/ */
void
slotAutoSave
();
void
slotAutoSave
(
QMap
<
double
,
QString
>
guidesData
);
private
slots
:
void
slotClipModified
(
const
QString
&
path
);
void
slotClipMissing
(
const
QString
&
path
);
void
slotClipAvailable
(
const
QString
&
path
);
...
...
@@ -273,6 +269,8 @@ signals:
void
guidesUpdated
();
/** @brief When creating a backup file, also save a thumbnail of current timeline */
void
saveTimelinePreview
(
const
QString
&
path
);
/** @brief Trigger the autosave timer start */
void
startAutoSave
();
};
#endif
...
...
src/mainwindow.cpp
View file @
9eadd8fe
...
...
@@ -1406,7 +1406,7 @@ void MainWindow::slotRenderProject()
connect
(
m_renderWidget
,
SIGNAL
(
openDvdWizard
(
QString
)),
this
,
SLOT
(
slotDvdWizard
(
QString
)));
if
(
project
)
{
m_renderWidget
->
setProfile
(
project
->
mltProfile
());
m_renderWidget
->
setGuides
(
p
roject
->
guides
Xml
(),
project
->
projectDuration
());
m_renderWidget
->
setGuides
(
p
Core
->
projectManager
()
->
currentTrackView
()
->
projectView
()
->
guides
Data
(),
project
->
projectDuration
());
m_renderWidget
->
setDocumentPath
(
project
->
projectFolder
().
path
()
+
QDir
::
separator
());
m_renderWidget
->
setRenderProfile
(
project
->
getRenderProperties
());
}
...
...
@@ -1481,6 +1481,7 @@ void MainWindow::connectDocument()
KdenliveDoc
*
project
=
pCore
->
projectManager
()
->
current
();
TrackView
*
trackView
=
pCore
->
projectManager
()
->
currentTrackView
();
pCore
->
binController
()
->
resetProfile
(
project
->
profilePath
());
connect
(
project
,
SIGNAL
(
startAutoSave
()),
pCore
->
projectManager
(),
SLOT
(
slotStartAutoSave
()));
// Resetting monitor profiles should now be handled by binController
//pCore->monitorManager()->resetProfiles(project->timecode());
KdenliveSettings
::
setProject_fps
(
project
->
fps
());
...
...
@@ -1507,7 +1508,7 @@ void MainWindow::connectDocument()
connect
(
project
,
SIGNAL
(
signalDeleteProjectClip
(
QString
)),
this
,
SLOT
(
slotDeleteClip
(
QString
)));
connect
(
project
,
SIGNAL
(
docModified
(
bool
)),
this
,
SLOT
(
slotUpdateDocumentState
(
bool
)));
connect
(
project
,
SIGNAL
(
guidesUpdated
()),
this
,
SLOT
(
slotGuidesUpdated
()));
connect
(
trackView
->
project
View
()
,
SIGNAL
(
guidesUpdated
()),
this
,
SLOT
(
slotGuidesUpdated
()));
connect
(
project
,
SIGNAL
(
saveTimelinePreview
(
QString
)),
trackView
,
SLOT
(
slotSaveTimelinePreview
(
QString
)));
connect
(
trackView
->
projectView
(),
SIGNAL
(
updateClipMarkers
(
ClipController
*
)),
this
,
SLOT
(
slotUpdateClipMarkers
(
ClipController
*
)));
...
...
@@ -1556,7 +1557,7 @@ void MainWindow::connectDocument()
if
(
m_renderWidget
)
{
slotCheckRenderStatus
();
m_renderWidget
->
setProfile
(
project
->
mltProfile
());
m_renderWidget
->
setGuides
(
p
roject
->
guides
Xml
(),
project
->
projectDuration
());
m_renderWidget
->
setGuides
(
p
Core
->
projectManager
()
->
currentTrackView
()
->
projectView
()
->
guides
Data
(),
project
->
projectDuration
());
m_renderWidget
->
setDocumentPath
(
project
->
projectFolder
().
path
()
+
QDir
::
separator
());
m_renderWidget
->
setRenderProfile
(
project
->
getRenderProperties
());
}
...
...
@@ -1594,7 +1595,7 @@ void MainWindow::slotZoneMoved(int start, int end)
void
MainWindow
::
slotGuidesUpdated
()
{
if
(
m_renderWidget
)
m_renderWidget
->
setGuides
(
pCore
->
projectManager
()
->
current
()
->
guides
Xml
(),
pCore
->
projectManager
()
->
current
()
->
projectDuration
());
m_renderWidget
->
setGuides
(
pCore
->
projectManager
()
->
current
TrackView
()
->
projectView
()
->
guides
Data
(),
pCore
->
projectManager
()
->
current
()
->
projectDuration
());
}
void
MainWindow
::
slotEditKeys
()
...
...
@@ -2778,22 +2779,22 @@ void MainWindow::slotPrepareRendering(bool scriptExport, bool zoneOnly, const QS
chapters
.
setAttribute
(
"fps"
,
project
->
fps
());
doc
.
appendChild
(
chapters
);
QDomElement
guidesxml
=
project
->
guidesXml
();
QDomNodeList
nodes
=
guidesxml
.
elementsByTagName
(
"guide"
);
for
(
int
i
=
0
;
i
<
nodes
.
count
();
++
i
)
{
QDomElement
e
=
nodes
.
item
(
i
).
toElement
();
if
(
!
e
.
isNull
())
{
QString
comment
=
e
.
attribute
(
"comment"
);
int
time
=
(
int
)
GenTime
(
e
.
attribute
(
"time"
).
toDouble
()).
frames
(
project
->
fps
());
if
(
time
>=
in
&&
time
<
out
)
{
if
(
zoneOnly
)
time
=
time
-
in
;
QDomElement
chapter
=
doc
.
createElement
(
"chapter"
);
chapters
.
appendChild
(
chapter
);
chapter
.
setAttribute
(
"title"
,
comment
);
chapter
.
setAttribute
(
"time"
,
time
);
}
QMap
<
double
,
QString
>
guidesData
=
pCore
->
projectManager
()
->
currentTrackView
()
->
projectView
()
->
guidesData
();
QMapIterator
<
double
,
QString
>
g
(
guidesData
);
QLocale
locale
;
while
(
g
.
hasNext
())
{
g
.
next
();
int
time
=
(
int
)
GenTime
(
g
.
key
()).
frames
(
project
->
fps
());
if
(
time
>=
in
&&
time
<
out
)
{
if
(
zoneOnly
)
time
=
time
-
in
;
QDomElement
chapter
=
doc
.
createElement
(
"chapter"
);
chapters
.
appendChild
(
chapter
);
chapter
.
setAttribute
(
"title"
,
g
.
value
());
chapter
.
setAttribute
(
"time"
,
time
);
}
}
if
(
chapters
.
childNodes
().
count
()
>
0
)
{
if
(
pCore
->
projectManager
()
->
currentTrackView
()
->
projectView
()
->
hasGuide
(
out
,
0
)
==
-
1
)
{
// Always insert a guide in pos 0
...
...
@@ -3049,7 +3050,7 @@ void MainWindow::slotUpdateProxySettings()
void
MainWindow
::
slotArchiveProject
()
{
QList
<
ClipController
*>
list
=
pCore
->
binController
()
->
getControllerList
();
QDomDocument
doc
=
pCore
->
projectManager
()
->
current
()
->
xmlSceneList
(
m_projectMonitor
->
sceneList
());
QDomDocument
doc
=
pCore
->
projectManager
()
->
current
()
->
xmlSceneList
(
m_projectMonitor
->
sceneList
()
,
pCore
->
projectManager
()
->
currentTrackView
()
->
projectView
()
->
guidesData
()
);
QPointer
<
ArchiveWidget
>
d
=
new
ArchiveWidget
(
pCore
->
projectManager
()
->
current
()
->
url
().
fileName
(),
doc
,
list
,
pCore
->
projectManager
()
->
currentTrackView
()
->
projectView
()
->
extractTransitionsLumas
(),
this
);
if
(
d
->
exec
())
{
m_messageLabel
->
setMessage
(
i18n
(
"Archiving project"
),
OperationCompletedMessage
);
...
...
src/mltcontroller/bincontroller.cpp
View file @
9eadd8fe
...
...
@@ -142,6 +142,26 @@ void BinController::initializeBin(Mlt::Playlist playlist)
}
}
QMap
<
double
,
QString
>
BinController
::
takeGuidesData
()
{
QLocale
locale
;
// Load guides
Mlt
::
Properties
guidesProperties
;
Mlt
::
Properties
playlistProps
(
m_binPlaylist
->
get_properties
());
guidesProperties
.
pass_values
(
playlistProps
,
"kdenlive:guide."
);
qDebug
()
<<
"***********
\n
FOUND GUIDES: "
<<
guidesProperties
.
count
()
<<
"
\n
**********"
;
QMap
<
double
,
QString
>
guidesData
;
for
(
int
i
=
0
;
i
<
guidesProperties
.
count
();
i
++
)
{
double
time
=
locale
.
toDouble
(
guidesProperties
.
get_name
(
i
));
guidesData
.
insert
(
time
,
guidesProperties
.
get
(
i
));
// Clear bin data
QString
propertyName
=
"kdenlive:guide."
+
QString
(
guidesProperties
.
get_name
(
i
));
m_binPlaylist
->
set
(
propertyName
.
toUtf8
().
constData
(),
(
char
*
)
NULL
);
}
return
guidesData
;
}
void
BinController
::
createIfNeeded
()
{
if
(
m_binPlaylist
)
return
;
...
...
src/mltcontroller/bincontroller.h
View file @
9eadd8fe
...
...
@@ -132,6 +132,7 @@ public:
const
QStringList
getBinIdsByResource
(
const
QUrl
&
url
)
const
;
void
replaceProducer
(
const
QString
&
id
,
Mlt
::
Producer
&
producer
);
void
storeMarker
(
const
QString
&
markerId
,
const
QString
&
markerHash
);
QMap
<
double
,
QString
>
takeGuidesData
();
public
slots
:
/** @brief Stored a Bin Folder id / name to MLT's bin playlist. Using an empry folderName deletes the property */
...
...
src/project/projectmanager.cpp
View file @
9eadd8fe
...
...
@@ -11,6 +11,7 @@ the Free Software Foundation, either version 3 of the License, or
#include
"projectmanager.h"
#include
"core.h"
#include
"bin/bin.h"
#include
"mltcontroller/bincontroller.h"
#include
"mainwindow.h"
#include
"kdenlivesettings.h"
#include
"monitor/monitormanager.h"
...
...
@@ -55,6 +56,9 @@ ProjectManager::ProjectManager(QObject* parent) :
connect
(
backupAction
,
SIGNAL
(
triggered
(
bool
)),
SLOT
(
slotOpenBackup
()));
m_notesPlugin
=
new
NotesPlugin
(
this
);
m_autoSaveTimer
.
setSingleShot
(
true
);
connect
(
&
m_autoSaveTimer
,
SIGNAL
(
timeout
()),
this
,
SLOT
(
slotAutoSave
()));
}
ProjectManager
::~
ProjectManager
()
...
...
@@ -186,7 +190,7 @@ bool ProjectManager::closeCurrentDocument(bool saveChanges)
break
;
}
}
m_autoSaveTimer
.
stop
();
pCore
->
window
()
->
slotTimelineClipSelected
(
NULL
,
false
);
pCore
->
monitorManager
()
->
clipMonitor
()
->
openClip
(
NULL
);
...
...
@@ -205,10 +209,11 @@ bool ProjectManager::closeCurrentDocument(bool saveChanges)
bool
ProjectManager
::
saveFileAs
(
const
QString
&
outputFileName
)
{
pCore
->
monitorManager
()
->
stopActiveMonitor
();
if
(
m_project
->
saveSceneList
(
outputFileName
,
pCore
->
monitorManager
()
->
projectMonitor
()
->
sceneList
())
==
false
)
{
if
(
m_project
->
saveSceneList
(
outputFileName
,
pCore
->
monitorManager
()
->
projectMonitor
()
->
sceneList
(),
m_trackView
->
projectView
()
->
guidesData
())
==
false
)
{
return
false
;
}
// Save timeline thumbnails
m_trackView
->
projectView
()
->
saveThumbnails
();
m_project
->
setUrl
(
QUrl
::
fromLocalFile
(
outputFileName
));
...
...
@@ -428,6 +433,7 @@ void ProjectManager::doOpenFile(const QUrl &url, KAutoSaveFile *stale)
bool
ok
;
m_trackView
=
new
TrackView
(
doc
,
pCore
->
window
()
->
m_tracksActionCollection
->
actions
(),
&
ok
,
pCore
->
window
());
m_trackView
->
loadGuides
(
pCore
->
binController
()
->
takeGuidesData
());
m_project
=
doc
;
pCore
->
window
()
->
connectDocument
();
...
...
@@ -537,3 +543,14 @@ KRecentFilesAction* ProjectManager::recentFilesAction()
}
void
ProjectManager
::
slotStartAutoSave
()
{
m_autoSaveTimer
.
start
(
3000
);
// will trigger slotAutoSave() in 3 seconds
}
void
ProjectManager
::
slotAutoSave
()
{
m_project
->
slotAutoSave
(
m_trackView
->
projectView
()
->
guidesData
());
}
src/project/projectmanager.h
View file @
9eadd8fe
...
...
@@ -13,6 +13,8 @@ the Free Software Foundation, either version 3 of the License, or
#include
<QObject>
#include
<QUrl>
#include
<QTimer>
#include
<KRecentFilesAction>
#include
"kdenlivecore_export.h"
...
...
@@ -24,7 +26,6 @@ class QAction;
class
QUrl
;
class
KAutoSaveFile
;
/**
* @class ProjectManager
* @brief Takes care of interaction with projects.
...
...
@@ -81,11 +82,16 @@ public slots:
*
* Checks if already open and whether backup exists */
void
openFile
(
const
QUrl
&
url
);
/** @brief Start autosave timer */
void
slotStartAutoSave
();
private
slots
:
void
slotRevert
();
/** @brief Open the project's backupdialog. */
void
slotOpenBackup
(
const
QUrl
&
url
=
QUrl
());
/** @brief Start autosaving the document. */
void
slotAutoSave
();
signals:
void
docOpened
(
KdenliveDoc
*
document
);
...
...
@@ -102,6 +108,8 @@ private:
KdenliveDoc
*
m_project
;
TrackView
*
m_trackView
;
QTimer
m_autoSaveTimer
;
QUrl
m_startUrl
;
QString
m_loadClipsOnOpen
;
...
...
src/timeline/customtrackview.cpp
View file @
9eadd8fe
...
...
@@ -3700,7 +3700,7 @@ void CustomTrackView::mouseReleaseEvent(QMouseEvent * event)
m_commandStack
->
push
(
command
);
m_dragGuide
->
updateGuide
(
GenTime
(
m_dragGuide
->
pos
().
x
(),
m_document
->
fps
()));
qSort
(
m_guides
.
begin
(),
m_guides
.
end
(),
sortGuidesList
);
m_document
->
syncGuides
(
m_guides
);
emit
guidesUpdated
(
);
}
m_dragGuide
=
NULL
;
m_dragItem
=
NULL
;
...
...
@@ -5658,6 +5658,15 @@ void CustomTrackView::buildGuidesMenu(QMenu *goMenu) const
goMenu
->
setEnabled
(
!
m_guides
.
isEmpty
());
}
QMap
<
double
,
QString
>
CustomTrackView
::
guidesData
()
const
{
QMap
<
double
,
QString
>
data
;
for
(
int
i
=
0
;
i
<
m_guides
.
count
();
++
i
)
{
data
.
insert
(
m_guides
.
at
(
i
)
->
position
().
seconds
(),
m_guides
.
at
(
i
)
->
label
());
}
return
data
;
}
void
CustomTrackView
::
editGuide
(
const
GenTime
&
oldPos
,
const
GenTime
&
pos
,
const
QString
&
comment
)
{
if
(
comment
.
isEmpty
()
&&
pos
<
GenTime
())
{
...
...
@@ -5684,7 +5693,7 @@ void CustomTrackView::editGuide(const GenTime &oldPos, const GenTime &pos, const
}
}
else
addGuide
(
pos
,
comment
);
qSort
(
m_guides
.
begin
(),
m_guides
.
end
(),
sortGuidesList
);
m_document
->
syncGuides
(
m_guides
);
emit
guidesUpdated
(
);
}
bool
CustomTrackView
::
addGuide
(
const
GenTime
&
pos
,
const
QString
&
comment
)
...
...
@@ -5699,7 +5708,7 @@ bool CustomTrackView::addGuide(const GenTime &pos, const QString &comment)
scene
()
->
addItem
(
g
);
m_guides
.
append
(
g
);
qSort
(
m_guides
.
begin
(),
m_guides
.
end
(),
sortGuidesList
);
m_document
->
syncGuides
(
m_guides
);
emit
guidesUpdated
(
);
return
true
;
}
...
...
src/timeline/customtrackview.h
View file @
9eadd8fe
...
...
@@ -221,6 +221,8 @@ public:
void
createGroupForSelectedItems
(
QList
<
QGraphicsItem
*>
&
selection
);
void
selectItemsRightOfFrame
(
int
frame
);
void
resetSelectionGroup
(
bool
selectItems
=
true
);
/** @brief Returns all infos necessary to save guides. */
QMap
<
double
,
QString
>
guidesData
()
const
;
public
slots
:
/** @brief Send seek request to MLT. */
...
...
@@ -536,6 +538,8 @@ signals:
void
updateRuler
();
/** @brief Send data from a clip to be imported as keyframes for effect / transition.*/
void
importKeyframes
(
GraphicsRectItem
type
,
const
QString
&
,
int
maximum
);
/** @brief Guides were changed, inform render widget*/
void
guidesUpdated
();
};
#endif
...
...
src/timeline/trackview.cpp
View file @
9eadd8fe
...
...
@@ -417,16 +417,6 @@ void TrackView::parseDocument(const QDomDocument &doc)
int
currentPos
=
propsXml
.
attribute
(
"position"
).
toInt
();
if
(
currentPos
>
0
)
m_trackview
->
initCursorPos
(
currentPos
);
// Add guides
QDomNodeList
guides
=
infoXml
.
elementsByTagName
(
"guide"
);
for
(
int
i
=
0
;
i
<
guides
.
count
();
++
i
)
{
e
=
guides
.
item
(
i
).
toElement
();
const
QString
comment
=
e
.
attribute
(
"comment"
);
const
GenTime
pos
=
GenTime
(
e
.
attribute
(
"time"
).
toDouble
());
m_trackview
->
addGuide
(
pos
,
comment
);
}
// Rebuild groups
QDomNodeList
groups
=
infoXml
.
elementsByTagName
(
"group"
);
...
...
@@ -775,6 +765,16 @@ int TrackView::slotAddProjectTrack(int ix, QDomElement xml, bool locked, const Q
return
position
;
}
void
TrackView
::
loadGuides
(
QMap
<
double
,
QString
>
guidesData
)
{
QMapIterator
<
double
,
QString
>
i
(
guidesData
);
while
(
i
.
hasNext
())
{
i
.
next
();
const
GenTime
pos
=
GenTime
(
i
.
key
());
m_trackview
->
addGuide
(
pos
,
i
.
value
());
}