Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit 4efa8316 authored by Nicolas Carion's avatar Nicolas Carion

[Timeline2][Model] Enforce new method calling scheme (+docs and tests)

parent e103e0be
......@@ -79,9 +79,9 @@ bool ClipModel::isValid()
return m_producer->is_valid();
}
bool ClipModel::slotRequestResize(int size, bool right, bool dry)
bool ClipModel::requestResize(int size, bool right, bool dry)
{
if (!dry && !slotRequestResize(size, right, true)) {
if (!dry && !requestResize(size, right, true)) {
return false;
}
if (size < 0 || size > m_producer->get_length()) {
......
......@@ -77,38 +77,23 @@ public:
/* Returns true if the underlying producer is valid
*/
bool isValid();
public:
protected:
/* @brief Performs a resize of the given clip.
Returns true if the operation succeeded, and otherwise nothing is modified
This is called whenever a resize of the clip is issued
If the resize is accepted, it should send back a signal to the QML interface.
This method is protected because it shouldn't be called directly. Call the function in the timeline instead.
If a snap point is within reach, the operation will be coerced to use it.
@param size is the new size of the clip
@param right is true if we change the right side of the clip, false otherwise
@param dry If this parameter is true, no action is actually executed, but we return true if it would be possible to do it.
*/
bool slotRequestResize(int size, bool right, bool dry = false);
/* This is called whenever a move of the clip is issued
If the move is accepted, it should send back a signal to the QML interface.
If a snap point is withing reach, the operation will be coerced to use it.
*/
void slotRequestMove(int newPosition);
/* Delete the current clip
*/
void slotDelete();
bool requestResize(int size, bool right, bool dry = false);
/* Split the current clip at the given position
*/
void slotSplit(int position);
signals:
void signalSizeChanged(int);
void signalPositionChanged(int);
protected:
/* Updates the stored position of the clip
This function is meant to be called by the trackmodel, not directly by the user.
If you whish to actually move the clip, use the requestMove slot.
......
......@@ -299,6 +299,12 @@ bool TimelineModel::requestClipChangeTrack(int cid, int tid, int position, bool
return ok;
}
bool TimelineModel::requestClipResize(int cid, int size, bool right, bool dry)
{
return m_allClips[cid]->requestResize(size, right, dry);
}
void TimelineModel::groupClips(std::unordered_set<int>&& ids)
{
m_groups->groupItems(std::forward<std::unordered_set<int>>(ids));
......
......@@ -38,6 +38,9 @@ class GroupsModel;
This class also serves to keep track of all objects. It holds pointers to all tracks and clips, and gives them unique IDs on creation. These Ids are used in any interactions with the objects and have nothing to do with Melt IDs.
This is the entry point for any modifications that has to be made on an element. The dataflow beyond this entry point may vary, for example when the user request a clip resize, the call is deferred to the clip itself, that check if there is enough data to extend by the requested amount, compute the new in and out, and then asks the track if there is enough room for extension. To avoid any confusion on which function to call first, rembember to always call the version in timeline.
It derives from AbstractItemModel to provide the model to the QML interface. An itemModel is organized with row and columns that contain the data. It can be hierarchical, meaning that a given index (row,column) can contain another level of rows and column.
Our organization is as follows: at the top level, each row contains a track. These rows are in the same order as in the actual timeline.
Then each of this row contains itself sub-rows that correspond to the clips. Here the order of these sub-rows is unrelated to the chronological order of the clips, but correspond to an insertion order in the track. This is because the order actually doesn't matter since the clips are rendered based on their positions rather than their row order. The insertion order in the track has been choosed because it is consistant with a valid ordering of the clips.
......@@ -111,7 +114,7 @@ public:
/* @brief Delete track based on its id */
void deleteTrackById(int id);
/* @brief Delete clipq based on its id */
/* @brief Delete clip based on its id */
void deleteClipById(int id);
/* @brief Returns the id of the track containing clip (-1 if it is not inserted)
......@@ -138,6 +141,15 @@ public:
*/
bool requestClipChangeTrack(int cid, int tid, int position, bool dry = false);
/* @brief Change the track in which the clip is included
Returns true on success. If it fails, nothing is modified.
@param cid is the ID of the clip
@param size is the new size of the clip
@param right is true if we change the right side of the clip, false otherwise
@param dry If this parameter is true, no action is actually executed, but we return true if it would be possible to do it.
*/
bool requestClipResize(int cid, int size, bool right, bool dry = false);
/* @brief Group together a set of ids
Typically, ids would be ids of clips, but for convenience, some of them can be ids of groups as well.
@param ids Set of ids to group
......
......@@ -55,25 +55,6 @@ public:
/* @brief returns the number of clips */
int getClipsCount();
/* @brief Performs an insertion of the given clip.
Returns true if the operation succeeded, and otherwise, the track is not modified.
@param clip is a shared pointer to the clip
@param position is the position where to insert the clip
@param dry If this parameter is true, no action is actually executed, but we return true if it would be possible to do it.
*/
bool requestClipInsertion(std::shared_ptr<ClipModel> clip, int position, bool dry = false);
/* @brief Performs an deletion of the given clip.
Returns true if the operation succeeded, and otherwise, the track is not modified.
@param cid is the id of the clip
@param dry If this parameter is true, no action is actually executed, but we return true if it would be possible to do it.
*/
bool requestClipDeletion(int cid, bool dry = false);
/* Perform a move operation on a clip. Returns true if the operation succeeded*/
bool requestClipMove(QSharedPointer<ClipModel> caller, int newPosition);
/* Perform a split at the requested position */
bool splitClip(QSharedPointer<ClipModel> caller, int position);
......@@ -81,8 +62,6 @@ public:
*/
operator Mlt::Producer&(){ return m_playlist;}
/* Implicit conversion operator to access the underlying producer
*/
// TODO make protected
QVariant getProperty(const QString &name);
void setProperty(const QString &name, const QString &value);
......@@ -90,7 +69,7 @@ public:
protected:
/* @brief Performs a resize of the given clip.
Returns true if the operation succeeded, and otherwise nothing is modified
This method is protected because it shouldn't be called directly. Call the function in the clip instead.
This method is protected because it shouldn't be called directly. Call the function in the timeline instead.
@param cid is the id of the clip
@param in is the new starting on the clip
@param out is the new ending on the clip
......@@ -99,6 +78,23 @@ protected:
*/
bool requestClipResize(int cid, int in, int out, bool right, bool dry = false);
/* @brief Performs an insertion of the given clip.
Returns true if the operation succeeded, and otherwise, the track is not modified.
This method is protected because it shouldn't be called directly. Call the function in the timeline instead.
@param clip is a shared pointer to the clip
@param position is the position where to insert the clip
@param dry If this parameter is true, no action is actually executed, but we return true if it would be possible to do it.
*/
bool requestClipInsertion(std::shared_ptr<ClipModel> clip, int position, bool dry = false);
/* @brief Performs an deletion of the given clip.
Returns true if the operation succeeded, and otherwise, the track is not modified.
This method is protected because it shouldn't be called directly. Call the function in the timeline instead.
@param cid is the id of the clip
@param dry If this parameter is true, no action is actually executed, but we return true if it would be possible to do it.
*/
bool requestClipDeletion(int cid, bool dry = false);
/*@brief Returns the (unique) construction id of the track*/
int getId() const;
......
......@@ -192,23 +192,23 @@ TEST_CASE("Clip manipulation", "[ClipModel]")
}
SECTION("Resize orphan clip"){
REQUIRE(timeline->m_allClips[cid2]->slotRequestResize(5, true, true));
REQUIRE(timeline->requestClipResize(cid2, 5, true, true));
REQUIRE(timeline->m_allClips[cid2]->getPlaytime() == length);
REQUIRE(timeline->m_allClips[cid2]->slotRequestResize(5, true));
REQUIRE(timeline->requestClipResize(cid2, 5, true));
REQUIRE(producer->get_playtime() == length);
REQUIRE(timeline->m_allClips[cid2]->getPlaytime() == 5);
REQUIRE_FALSE(timeline->m_allClips[cid2]->slotRequestResize(10, false));
REQUIRE_FALSE(timeline->m_allClips[cid2]->slotRequestResize(length + 1, true));
REQUIRE_FALSE(timeline->requestClipResize(cid2, 10, false));
REQUIRE_FALSE(timeline->requestClipResize(cid2, length + 1, true));
REQUIRE(timeline->m_allClips[cid2]->getPlaytime() == 5);
REQUIRE_FALSE(timeline->m_allClips[cid2]->slotRequestResize(length + 1, true, true));
REQUIRE_FALSE(timeline->requestClipResize(cid2, length + 1, true, true));
REQUIRE(timeline->m_allClips[cid2]->getPlaytime() == 5);
REQUIRE(timeline->m_allClips[cid2]->slotRequestResize(2, false));
REQUIRE(timeline->requestClipResize(cid2, 2, false));
REQUIRE(timeline->m_allClips[cid2]->getPlaytime() == 2);
REQUIRE_FALSE(timeline->m_allClips[cid2]->slotRequestResize(length, true));
REQUIRE_FALSE(timeline->requestClipResize(cid2, length, true));
REQUIRE(timeline->m_allClips[cid2]->getPlaytime() == 2);
CAPTURE(timeline->m_allClips[cid2]->m_producer->get_in());
REQUIRE_FALSE(timeline->m_allClips[cid2]->slotRequestResize(length - 2, true));
REQUIRE(timeline->m_allClips[cid2]->slotRequestResize(length - 3, true));
REQUIRE_FALSE(timeline->requestClipResize(cid2, length - 2, true));
REQUIRE(timeline->requestClipResize(cid2, length - 3, true));
REQUIRE(timeline->m_allClips[cid2]->getPlaytime() == length - 3);
}
......@@ -217,7 +217,7 @@ TEST_CASE("Clip manipulation", "[ClipModel]")
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->m_allClips[cid1]->slotRequestResize(5, true));
REQUIRE(timeline->requestClipResize(cid1, 5, true));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->m_allClips[cid1]->getPlaytime() == 5);
......@@ -228,17 +228,17 @@ TEST_CASE("Clip manipulation", "[ClipModel]")
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(producer->get_playtime() == length);
REQUIRE_FALSE(timeline->m_allClips[cid1]->slotRequestResize(6, true));
REQUIRE_FALSE(timeline->m_allClips[cid1]->slotRequestResize(6, false));
REQUIRE_FALSE(timeline->requestClipResize(cid1, 6, true));
REQUIRE_FALSE(timeline->requestClipResize(cid1, 6, false));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->m_allClips[cid2]->slotRequestResize(length - 5, false));
REQUIRE(timeline->requestClipResize(cid2, length - 5, false));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getClipPosition(cid2) == 10);
REQUIRE(timeline->m_allClips[cid1]->slotRequestResize(10, true));
REQUIRE(timeline->requestClipResize(cid1, 10, true));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid1) == 2);
......@@ -255,7 +255,7 @@ TEST_CASE("Clip manipulation", "[ClipModel]")
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
REQUIRE(timeline->getTrackClipsCount(tid2) == 1);
REQUIRE(timeline->m_allClips[cid1]->slotRequestResize(5, false));
REQUIRE(timeline->requestClipResize(cid1, 5, false));
REQUIRE(timeline->getTrackById(tid1)->checkConsistency());
REQUIRE(timeline->getTrackById(tid2)->checkConsistency());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment