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
0492874a
Commit
0492874a
authored
Dec 04, 2021
by
Jean-Baptiste Mardelle
Browse files
Add tests to prevent project corruption on color/title/image clip resize as happened in 21.08.3
parent
90b1e4f5
Pipeline
#105103
passed with stage
in 8 minutes and 44 seconds
Changes
16
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/bin/bin.cpp
View file @
0492874a
...
...
@@ -2910,13 +2910,7 @@ QStringList Bin::getBinFolderClipIds(const QString &id) const
std
::
shared_ptr
<
ProjectClip
>
Bin
::
getBinClip
(
const
QString
&
id
)
{
std
::
shared_ptr
<
ProjectClip
>
clip
=
nullptr
;
if
(
id
.
contains
(
QLatin1Char
(
'_'
)))
{
clip
=
m_itemModel
->
getClipByBinID
(
id
.
section
(
QLatin1Char
(
'_'
),
0
,
0
));
}
else
if
(
!
id
.
isEmpty
())
{
clip
=
m_itemModel
->
getClipByBinID
(
id
);
}
return
clip
;
return
m_itemModel
->
getClipByBinID
(
id
);
}
const
QString
Bin
::
getBinClipName
(
const
QString
&
id
)
const
...
...
src/dialogs/speechdialog.cpp
View file @
0492874a
...
...
@@ -120,7 +120,7 @@ void SpeechDialog::slotProcessSpeech(QPoint zone)
audio
=
m_tmpAudio
->
fileName
();
}
m_tmpAudio
->
close
();
pCore
->
getMonitor
(
Kdenlive
::
ProjectMonitor
)
->
sceneList
(
QDir
::
temp
().
absolutePath
(),
sceneList
);
m_timeline
->
sceneList
(
QDir
::
temp
().
absolutePath
(),
sceneList
);
Mlt
::
Producer
producer
(
*
m_timeline
->
tractor
()
->
profile
(),
"xml"
,
sceneList
.
toUtf8
().
constData
());
qDebug
()
<<
"=== STARTING RENDER B"
;
Mlt
::
Consumer
xmlConsumer
(
*
m_timeline
->
tractor
()
->
profile
(),
"avformat"
,
audio
.
toUtf8
().
constData
());
...
...
src/doc/kdenlivedoc.cpp
View file @
0492874a
...
...
@@ -1289,6 +1289,11 @@ void KdenliveDoc::slotProxyCurrentItem(bool doProxy, QList<std::shared_ptr<Proje
}
}
double
KdenliveDoc
::
getDocumentVersion
()
const
{
return
DOCUMENTVERSION
;
}
QMap
<
QString
,
QString
>
KdenliveDoc
::
documentProperties
()
{
m_documentProperties
.
insert
(
QStringLiteral
(
"version"
),
QString
::
number
(
DOCUMENTVERSION
));
...
...
src/doc/kdenlivedoc.h
View file @
0492874a
...
...
@@ -167,6 +167,10 @@ public:
void
initializeSubtitles
(
const
std
::
shared_ptr
<
SubtitleModel
>
m_subtitle
);
/** @brief Returns a path for current document's subtitle file. If final is true, this will be the project filename with ".srt" appended. Otherwise a file in /tmp */
const
QString
subTitlePath
(
bool
final
);
/** @brief Creates a new project. */
QDomDocument
createEmptyDocument
(
int
videotracks
,
int
audiotracks
);
/** @brief Return the document version. */
double
getDocumentVersion
()
const
;
private:
QUrl
m_url
;
...
...
@@ -204,7 +208,6 @@ private:
QString
searchFileRecursively
(
const
QDir
&
dir
,
const
QString
&
matchSize
,
const
QString
&
matchHash
)
const
;
/** @brief Creates a new project. */
QDomDocument
createEmptyDocument
(
int
videotracks
,
int
audiotracks
);
QDomDocument
createEmptyDocument
(
const
QList
<
TrackInfo
>
&
tracks
);
/** @brief Updates the project folder location entry in the kdenlive file dialogs to point to the current project folder. */
...
...
src/monitor/glwidget.cpp
View file @
0492874a
...
...
@@ -1383,39 +1383,6 @@ void GLWidget::resetConsumer(bool fullReset)
reconfigure
();
}
const
QString
GLWidget
::
sceneList
(
const
QString
&
root
,
const
QString
&
fullPath
,
QString
filterData
)
{
LocaleHandling
::
resetLocale
();
QString
playlist
;
Mlt
::
Consumer
xmlConsumer
(
pCore
->
getCurrentProfile
()
->
profile
(),
"xml"
,
fullPath
.
isEmpty
()
?
"kdenlive_playlist"
:
fullPath
.
toUtf8
().
constData
());
if
(
!
root
.
isEmpty
())
{
xmlConsumer
.
set
(
"root"
,
root
.
toUtf8
().
constData
());
}
if
(
!
xmlConsumer
.
is_valid
())
{
return
QString
();
}
xmlConsumer
.
set
(
"store"
,
"kdenlive"
);
xmlConsumer
.
set
(
"time_format"
,
"clock"
);
// Disabling meta creates cleaner files, but then we don't have access to metadata on the fly (meta channels, etc)
// And we must use "avformat" instead of "avformat-novalidate" on project loading which causes a big delay on project opening
// xmlConsumer.set("no_meta", 1);
Mlt
::
Service
s
(
m_producer
->
get_service
());
std
::
unique_ptr
<
Mlt
::
Filter
>
filter
=
nullptr
;
if
(
!
filterData
.
isEmpty
())
{
filter
=
std
::
make_unique
<
Mlt
::
Filter
>
(
pCore
->
getCurrentProfile
()
->
profile
(),
QString
(
"dynamictext:%1"
).
arg
(
filterData
).
toUtf8
().
constData
());
filter
->
set
(
"fgcolour"
,
"#ffffff"
);
filter
->
set
(
"bgcolour"
,
"#bb333333"
);
s
.
attach
(
*
filter
.
get
());
}
xmlConsumer
.
connect
(
s
);
xmlConsumer
.
run
();
if
(
filter
)
{
s
.
detach
(
*
filter
.
get
());
}
playlist
=
fullPath
.
isEmpty
()
?
QString
::
fromUtf8
(
xmlConsumer
.
get
(
"kdenlive_playlist"
))
:
fullPath
;
return
playlist
;
}
void
GLWidget
::
updateTexture
(
GLuint
yName
,
GLuint
uName
,
GLuint
vName
)
{
m_texture
[
0
]
=
yName
;
...
...
src/monitor/glwidget.h
View file @
0492874a
...
...
@@ -76,9 +76,6 @@ public:
// TODO: currently unused
int
reconfigureMulti
(
const
QString
&
params
,
const
QString
&
path
,
Mlt
::
Profile
*
profile
);
void
stopCapture
();
/** @brief Get the current MLT producer playlist.
* @return A string describing the playlist */
const
QString
sceneList
(
const
QString
&
root
,
const
QString
&
fullPath
=
QString
(),
QString
filterData
=
QString
());
int
displayWidth
()
const
{
return
m_rect
.
width
();
}
void
updateAudioForAnalysis
();
...
...
src/monitor/monitor.cpp
View file @
0492874a
...
...
@@ -1931,11 +1931,6 @@ void Monitor::resetConsumer(bool fullReset)
m_glMonitor
->
resetConsumer
(
fullReset
);
}
const
QString
Monitor
::
sceneList
(
const
QString
&
root
,
const
QString
&
fullPath
,
const
QString
overlayData
)
{
return
m_glMonitor
->
sceneList
(
root
,
fullPath
,
overlayData
);
}
void
Monitor
::
updateClipZone
(
const
QPoint
zone
)
{
if
(
m_controller
==
nullptr
)
{
...
...
src/monitor/monitor.h
View file @
0492874a
...
...
@@ -70,7 +70,6 @@ public:
void
resetConsumer
(
bool
fullReset
);
void
setCustomProfile
(
const
QString
&
profile
,
const
Timecode
&
tc
);
void
setupMenu
(
QMenu
*
goMenu
,
QMenu
*
overlayMenu
,
QAction
*
playZone
,
QAction
*
loopZone
,
QMenu
*
markerMenu
=
nullptr
,
QAction
*
loopClip
=
nullptr
);
const
QString
sceneList
(
const
QString
&
root
,
const
QString
&
fullPath
=
QString
(),
const
QString
overlayData
=
QString
());
const
QString
activeClipId
();
int
position
();
void
updateTimecodeFormat
();
...
...
src/project/projectmanager.cpp
View file @
0492874a
...
...
@@ -238,6 +238,35 @@ void ProjectManager::newFile(QString profileName, bool showProjectSettings)
m_lastSave
.
start
();
}
void
ProjectManager
::
testSetActiveDocument
(
KdenliveDoc
*
doc
,
std
::
shared_ptr
<
TimelineItemModel
>
timeline
)
{
m_project
=
doc
;
m_mainTimelineModel
=
timeline
;
}
bool
ProjectManager
::
testSaveFileAs
(
const
QString
&
outputFileName
)
{
QString
saveFolder
=
QFileInfo
(
outputFileName
).
absolutePath
();
QMap
<
QString
,
QString
>
docProperties
;
docProperties
.
insert
(
QStringLiteral
(
"version"
),
QString
::
number
(
m_project
->
getDocumentVersion
()));
pCore
->
projectItemModel
()
->
saveDocumentProperties
(
docProperties
,
QMap
<
QString
,
QString
>
(),
m_project
->
getGuideModel
());
QString
scene
=
m_mainTimelineModel
->
sceneList
(
saveFolder
);
QSaveFile
file
(
outputFileName
);
if
(
!
file
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Text
))
{
qDebug
()
<<
"////// ERROR writing to file: "
<<
outputFileName
;
return
false
;
}
file
.
write
(
scene
.
toUtf8
());
if
(
!
file
.
commit
())
{
qDebug
()
<<
"Cannot write to file %1"
;
return
false
;
}
return
true
;
}
bool
ProjectManager
::
closeCurrentDocument
(
bool
saveChanges
,
bool
quit
)
{
// Disable autosave
...
...
@@ -746,7 +775,7 @@ QString ProjectManager::projectSceneList(const QString &outputFolder, const QStr
pCore
->
window
()
->
getMainTimeline
()
->
controller
()
->
requestEndTrimmingMode
();
}
pCore
->
mixer
()
->
pauseMonitoring
(
true
);
QString
scene
=
pCore
->
monitorManager
()
->
projectMonitor
()
->
sceneList
(
outputFolder
,
QString
(),
overlayData
);
QString
scene
=
m_mainTimelineModel
->
sceneList
(
outputFolder
,
QString
(),
overlayData
);
pCore
->
mixer
()
->
pauseMonitoring
(
false
);
if
(
isMultiTrack
)
{
pCore
->
window
()
->
getMainTimeline
()
->
controller
()
->
slotMultitrackView
(
true
,
false
);
...
...
@@ -762,7 +791,9 @@ QString ProjectManager::projectSceneList(const QString &outputFolder, const QStr
void
ProjectManager
::
setDocumentNotes
(
const
QString
&
notes
)
{
m_notesPlugin
->
widget
()
->
setHtml
(
notes
);
if
(
m_notesPlugin
)
{
m_notesPlugin
->
widget
()
->
setHtml
(
notes
);
}
}
QString
ProjectManager
::
documentNotes
()
const
...
...
src/project/projectmanager.h
View file @
0492874a
...
...
@@ -94,6 +94,12 @@ public:
/** @brief Add requested audio tracks number to project.
*/
void
addAudioTracks
(
int
tracksCount
);
/** @brief This method is only there for tests, do not use in real app.
*/
void
testSetActiveDocument
(
KdenliveDoc
*
doc
,
std
::
shared_ptr
<
TimelineItemModel
>
timeline
);
/** @brief This method is only there for tests, do not use in real app.
*/
bool
testSaveFileAs
(
const
QString
&
outputFileName
);
public
slots
:
void
newFile
(
QString
profileName
,
bool
showProjectSettings
=
true
);
...
...
src/timeline2/model/builders/meltBuilder.cpp
View file @
0492874a
...
...
@@ -47,7 +47,6 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
std
::
unordered_map
<
QString
,
QString
>
binIdCorresp
;
QStringList
expandedFolders
;
pCore
->
projectItemModel
()
->
loadBinPlaylist
(
&
tractor
,
timeline
->
tractor
(),
binIdCorresp
,
expandedFolders
,
progressDialog
);
pCore
->
bin
()
->
checkMissingProxies
();
QStringList
foldersToExpand
;
// Find updated ids for expanded folders
for
(
const
QString
&
folderId
:
expandedFolders
)
{
...
...
@@ -55,7 +54,10 @@ bool constructTimelineFromMelt(const std::shared_ptr<TimelineItemModel> &timelin
foldersToExpand
<<
binIdCorresp
.
at
(
folderId
);
}
}
pCore
->
bin
()
->
loadFolderState
(
foldersToExpand
);
if
(
pCore
->
window
())
{
pCore
->
bin
()
->
checkMissingProxies
();
pCore
->
bin
()
->
loadFolderState
(
foldersToExpand
);
}
QSet
<
QString
>
reserved_names
{
QLatin1String
(
"playlistmain"
),
QLatin1String
(
"timeline_preview"
),
QLatin1String
(
"timeline_overlay"
),
QLatin1String
(
"black_track"
),
QLatin1String
(
"overlay_track"
)};
bool
ok
=
true
;
...
...
@@ -373,7 +375,7 @@ bool constructTrackFromMelt(const std::shared_ptr<TimelineItemModel> &timeline,
}
bool
ok
=
false
;
int
cid
=
-
1
;
if
(
pCore
->
bin
()
->
get
Bin
Clip
(
binId
))
{
if
(
pCore
->
projectItemModel
()
->
getClip
ByBinID
(
binId
))
{
PlaylistState
::
ClipState
st
=
inferState
(
clip
,
audioTrack
);
bool
enforceTopPlaylist
=
false
;
if
(
playlist
>
0
)
{
...
...
src/timeline2/model/timelinemodel.cpp
View file @
0492874a
...
...
@@ -39,6 +39,7 @@
#include <set>
#include "macros.hpp"
#include <localeHandling.h>
#ifdef CRASH_AUTO_TEST
#include "logger.hpp"
...
...
@@ -3280,6 +3281,9 @@ int TimelineModel::requestItemResize(int itemId, int size, bool right, bool logU
finalSize
=
qMax
(
0
,
getItemPosition
(
id
))
+
getItemPlaytime
(
id
)
-
finalPos
;
}
result
=
result
&&
requestItemResize
(
id
,
finalSize
,
right
,
logUndo
,
undo
,
redo
);
if
(
!
result
)
{
break
;
}
if
(
id
==
itemId
)
{
size
=
finalSize
;
}
...
...
@@ -5239,6 +5243,39 @@ std::shared_ptr<Mlt::Producer> TimelineModel::producer()
return
std
::
make_shared
<
Mlt
::
Producer
>
(
tractor
());
}
const
QString
TimelineModel
::
sceneList
(
const
QString
&
root
,
const
QString
&
fullPath
,
QString
filterData
)
{
LocaleHandling
::
resetLocale
();
QString
playlist
;
Mlt
::
Consumer
xmlConsumer
(
*
m_profile
,
"xml"
,
fullPath
.
isEmpty
()
?
"kdenlive_playlist"
:
fullPath
.
toUtf8
().
constData
());
if
(
!
root
.
isEmpty
())
{
xmlConsumer
.
set
(
"root"
,
root
.
toUtf8
().
constData
());
}
if
(
!
xmlConsumer
.
is_valid
())
{
return
QString
();
}
xmlConsumer
.
set
(
"store"
,
"kdenlive"
);
xmlConsumer
.
set
(
"time_format"
,
"clock"
);
// Disabling meta creates cleaner files, but then we don't have access to metadata on the fly (meta channels, etc)
// And we must use "avformat" instead of "avformat-novalidate" on project loading which causes a big delay on project opening
// xmlConsumer.set("no_meta", 1);
Mlt
::
Service
s
(
m_tractor
->
get_service
());
std
::
unique_ptr
<
Mlt
::
Filter
>
filter
=
nullptr
;
if
(
!
filterData
.
isEmpty
())
{
filter
=
std
::
make_unique
<
Mlt
::
Filter
>
(
*
m_profile
,
QString
(
"dynamictext:%1"
).
arg
(
filterData
).
toUtf8
().
constData
());
filter
->
set
(
"fgcolour"
,
"#ffffff"
);
filter
->
set
(
"bgcolour"
,
"#bb333333"
);
s
.
attach
(
*
filter
.
get
());
}
xmlConsumer
.
connect
(
s
);
xmlConsumer
.
run
();
if
(
filter
)
{
s
.
detach
(
*
filter
.
get
());
}
playlist
=
fullPath
.
isEmpty
()
?
QString
::
fromUtf8
(
xmlConsumer
.
get
(
"kdenlive_playlist"
))
:
fullPath
;
return
playlist
;
}
void
TimelineModel
::
checkRefresh
(
int
start
,
int
end
)
{
if
(
m_blockRefresh
)
{
...
...
src/timeline2/model/timelinemodel.hpp
View file @
0492874a
...
...
@@ -442,6 +442,9 @@ public:
/** @brief Returns a list of proxied clips at position pos
*/
QStringList
getProxiesAt
(
int
position
);
/** @brief Returns the current project xml playlist for saving
*/
const
QString
sceneList
(
const
QString
&
root
,
const
QString
&
fullPath
=
QString
(),
QString
filterData
=
QString
());
protected:
/** @brief Creates a new clip instance without inserting it.
...
...
src/timeline2/view/previewmanager.cpp
View file @
0492874a
...
...
@@ -6,12 +6,14 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include "previewmanager.h"
#include "core.h"
#include "mainwindow.h"
#include "doc/docundostack.hpp"
#include "doc/kdenlivedoc.h"
#include "kdenlivesettings.h"
#include "monitor/monitor.h"
#include "profiles/profilemodel.hpp"
#include "timeline2/view/timelinecontroller.h"
#include "timeline2/view/timelinewidget.h"
#include <KLocalizedString>
#include <QProcess>
...
...
@@ -516,7 +518,7 @@ void PreviewManager::startPreviewRender()
// clear log
m_errorLog
.
clear
();
const
QString
sceneList
=
m_cacheDir
.
absoluteFilePath
(
QStringLiteral
(
"preview.mlt"
));
pCore
->
getMonitor
(
Kdenlive
::
ProjectMonitor
)
->
sceneList
(
m_cacheDir
.
absolutePath
(),
sceneList
);
pCore
->
window
()
->
getMainTimeline
()
->
model
(
)
->
sceneList
(
m_cacheDir
.
absolutePath
(),
sceneList
);
m_previewTimer
.
stop
();
doPreviewRender
(
sceneList
);
}
...
...
tests/CMakeLists.txt
View file @
0492874a
...
...
@@ -5,6 +5,7 @@ add_executable(runTests
abortutil.cpp
compositiontest.cpp
effectstest.cpp
filetest.cpp
mixtest.cpp
groupstest.cpp
keyframetest.cpp
...
...
tests/filetest.cpp
0 → 100644
View file @
0492874a
#include "doc/kdenlivedoc.h"
#include "timeline2/model/builders/meltBuilder.hpp"
#include "test_utils.hpp"
using
namespace
fakeit
;
Mlt
::
Profile
profile_file
;
TEST_CASE
(
"Save File"
,
"[SF]"
)
{
auto
binModel
=
pCore
->
projectItemModel
();
binModel
->
clean
();
std
::
shared_ptr
<
DocUndoStack
>
undoStack
=
std
::
make_shared
<
DocUndoStack
>
(
nullptr
);
std
::
shared_ptr
<
MarkerListModel
>
guideModel
=
std
::
make_shared
<
MarkerListModel
>
(
undoStack
);
// Here we do some trickery to enable testing.
// we mock a doc to stub the getDocumentProperty
Mock
<
KdenliveDoc
>
docMock
;
When
(
Method
(
docMock
,
getDocumentProperty
)).
AlwaysDo
([](
const
QString
&
name
,
const
QString
&
defaultValue
)
{
Q_UNUSED
(
name
)
Q_UNUSED
(
defaultValue
)
qDebug
()
<<
"Intercepted call"
;
return
QStringLiteral
(
"dummyId"
);
});
KdenliveDoc
&
mockedDoc
=
docMock
.
get
();
// We mock the project class so that the undoStack function returns our undoStack, and our mocked document
Mock
<
ProjectManager
>
pmMock
;
When
(
Method
(
pmMock
,
undoStack
)).
AlwaysReturn
(
undoStack
);
When
(
Method
(
pmMock
,
cacheDir
)).
AlwaysReturn
(
QDir
(
QStandardPaths
::
writableLocation
(
QStandardPaths
::
CacheLocation
)));
When
(
Method
(
pmMock
,
current
)).
AlwaysReturn
(
&
mockedDoc
);
ProjectManager
&
mocked
=
pmMock
.
get
();
pCore
->
m_projectManager
=
&
mocked
;
// We also mock timeline object to spy few functions and mock others
TimelineItemModel
tim
(
&
profile_file
,
undoStack
);
Mock
<
TimelineItemModel
>
timMock
(
tim
);
auto
timeline
=
std
::
shared_ptr
<
TimelineItemModel
>
(
&
timMock
.
get
(),
[](...)
{});
TimelineItemModel
::
finishConstruct
(
timeline
,
guideModel
);
mocked
.
testSetActiveDocument
(
&
mockedDoc
,
timeline
);
QDir
dir
=
QDir
::
temp
();
std
::
unordered_map
<
QString
,
QString
>
binIdCorresp
;
QStringList
expandedFolders
;
QDomDocument
doc
=
mockedDoc
.
createEmptyDocument
(
2
,
2
);
QScopedPointer
<
Mlt
::
Producer
>
xmlProd
(
new
Mlt
::
Producer
(
profile_file
,
"xml-string"
,
doc
.
toString
().
toUtf8
()));
Mlt
::
Service
s
(
*
xmlProd
);
Mlt
::
Tractor
tractor
(
s
);
binModel
->
loadBinPlaylist
(
&
tractor
,
timeline
->
tractor
(),
binIdCorresp
,
expandedFolders
,
nullptr
);
RESET
(
timMock
)
QString
binId
=
createProducerWithSound
(
profile_file
,
binModel
);
QString
binId2
=
createProducer
(
profile_file
,
"red"
,
binModel
,
20
,
false
);
int
tid2b
=
TrackModel
::
construct
(
timeline
,
-
1
,
-
1
,
QString
(),
true
);
int
tid2
=
TrackModel
::
construct
(
timeline
,
-
1
,
-
1
,
QString
(),
true
);
int
tid1
=
TrackModel
::
construct
(
timeline
);
int
tid1b
=
TrackModel
::
construct
(
timeline
);
// Setup timeline audio drop info
QMap
<
int
,
QString
>
audioInfo
;
audioInfo
.
insert
(
1
,
QStringLiteral
(
"stream1"
));
timeline
->
m_binAudioTargets
=
audioInfo
;
timeline
->
m_videoTarget
=
tid1
;
SECTION
(
"Simple insert and save"
)
{
// Insert 2 clips (length=20, pos = 80 / 100)
int
cid1
=
-
1
;
REQUIRE
(
timeline
->
requestClipInsertion
(
binId2
,
tid1
,
80
,
cid1
,
true
,
true
,
false
));
int
l
=
timeline
->
getClipPlaytime
(
cid1
);
int
cid2
=
-
1
;
REQUIRE
(
timeline
->
requestClipInsertion
(
binId2
,
tid1
,
80
+
l
,
cid2
,
true
,
true
,
false
));
// Resize first clip (length=100)
REQUIRE
(
timeline
->
requestItemResize
(
cid1
,
100
,
false
)
==
100
);
auto
state
=
[
&
]()
{
REQUIRE
(
timeline
->
checkConsistency
());
REQUIRE
(
timeline
->
getTrackClipsCount
(
tid1
)
==
2
);
REQUIRE
(
timeline
->
getClipTrackId
(
cid1
)
==
tid1
);
REQUIRE
(
timeline
->
getClipTrackId
(
cid2
)
==
tid1
);
REQUIRE
(
timeline
->
getClipPosition
(
cid1
)
==
0
);
REQUIRE
(
timeline
->
getClipPosition
(
cid2
)
==
100
);
REQUIRE
(
timeline
->
getClipPlaytime
(
cid1
)
==
100
);
REQUIRE
(
timeline
->
getClipPlaytime
(
cid2
)
==
20
);
};
state
();
mocked
.
testSaveFileAs
(
dir
.
absoluteFilePath
(
QStringLiteral
(
"test.kdenlive"
)));
// Undo resize
undoStack
->
undo
();
// Undo first insert
undoStack
->
undo
();
// Undo second insert
undoStack
->
undo
();
}
binModel
->
clean
();
SECTION
(
"Reopen and check in/out points"
)
{
QString
path
=
dir
.
absoluteFilePath
(
QStringLiteral
(
"test.kdenlive"
));
QFile
file
(
path
);
REQUIRE
(
file
.
open
(
QIODevice
::
ReadOnly
|
QIODevice
::
Text
)
==
true
);
QByteArray
playlist
=
file
.
readAll
();
file
.
close
();
QScopedPointer
<
Mlt
::
Producer
>
xmlProd
(
new
Mlt
::
Producer
(
profile_file
,
"xml-string"
,
playlist
));
Mlt
::
Service
s
(
*
xmlProd
);
Mlt
::
Tractor
tractor
(
s
);
bool
projectErrors
;
constructTimelineFromMelt
(
timeline
,
tractor
,
nullptr
,
QString
(),
&
projectErrors
);
int
tid1
=
timeline
->
getTrackIndexFromPosition
(
3
);
int
cid1
=
timeline
->
getClipByStartPosition
(
tid1
,
0
);
int
cid2
=
timeline
->
getClipByStartPosition
(
tid1
,
100
);
REQUIRE
(
cid1
>
-
1
);
REQUIRE
(
cid2
>
-
1
);
auto
state
=
[
&
]()
{
REQUIRE
(
timeline
->
checkConsistency
());
REQUIRE
(
timeline
->
getTrackClipsCount
(
tid1
)
==
2
);
REQUIRE
(
timeline
->
getClipTrackId
(
cid1
)
==
tid1
);
REQUIRE
(
timeline
->
getClipTrackId
(
cid2
)
==
tid1
);
REQUIRE
(
timeline
->
getClipPosition
(
cid1
)
==
0
);
REQUIRE
(
timeline
->
getClipPosition
(
cid2
)
==
100
);
REQUIRE
(
timeline
->
getClipPlaytime
(
cid1
)
==
100
);
REQUIRE
(
timeline
->
getClipPlaytime
(
cid2
)
==
20
);
};
state
();
QFile
::
remove
(
dir
.
absoluteFilePath
(
QStringLiteral
(
"test.kdenlive"
)));
}
binModel
->
clean
();
pCore
->
m_projectManager
=
nullptr
;
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment