Commit bdfa69d7 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Show timeline usage in clip monitor

parent 2a5bd722
Pipeline #97811 canceled with stage
......@@ -1850,6 +1850,9 @@ void Bin::setMonitor(Monitor *monitor)
connect(m_monitor, &Monitor::refreshCurrentClip, this, &Bin::slotOpenCurrent);
connect(this, &Bin::openClip, [&](std::shared_ptr<ProjectClip> clip, int in, int out) {
m_monitor->slotOpenClip(clip, in, out);
if (clip && clip->hasLimitedDuration()) {
clip->refreshBounds();
}
pCore->textEditWidget()->openClip(clip);
});
}
......
......@@ -96,6 +96,12 @@ ProjectClip::ProjectClip(const QString &id, const QIcon &thumb, const std::share
}
// Make sure we have a hash for this clip
hash();
if (m_hasLimitedDuration) {
connect(&m_boundaryTimer, &QTimer::timeout, this, &ProjectClip::refreshBounds);
m_boundaryTimer.setSingleShot(true);
m_boundaryTimer.setInterval(500);
}
connect(m_markerModel.get(), &MarkerListModel::modelChanged, this, [&]() {
setProducerProperty(QStringLiteral("kdenlive:markers"), m_markerModel->toJson());
});
......@@ -547,6 +553,13 @@ bool ProjectClip::setProducer(std::shared_ptr<Mlt::Producer> producer)
m_videoProducers.clear();
m_timewarpProducers.clear();
emit refreshPropertiesPanel();
if (m_hasLimitedDuration) {
connect(&m_boundaryTimer, &QTimer::timeout, this, &ProjectClip::refreshBounds);
m_boundaryTimer.setSingleShot(true);
m_boundaryTimer.setInterval(500);
} else {
disconnect(&m_boundaryTimer, &QTimer::timeout, this, &ProjectClip::refreshBounds);
}
replaceInTimeline();
updateTimelineClips({TimelineModel::IsProxyRole});
bool generateProxy = false;
......@@ -1670,11 +1683,30 @@ void ProjectClip::registerTimelineClip(std::weak_ptr<TimelineModel> timeline, in
}
m_registeredClips[clipId] = std::move(timeline);
setRefCount(uint(m_registeredClips.size()), m_audioCount);
emit registeredClipChanged();
}
void ProjectClip::checkClipBounds()
{
m_boundaryTimer.start();
}
void ProjectClip::refreshBounds()
{
QVector <QPoint> boundaries;
for (const auto &registeredClip : m_registeredClips) {
if (auto ptr = registeredClip.second.lock()) {
QPoint point = ptr->getClipInDuration(registeredClip.first);
if (!boundaries.contains(point)) {
boundaries << point;
}
}
}
emit boundsChanged(boundaries);
}
void ProjectClip::deregisterTimelineClip(int clipId, bool audioClip)
{
qDebug() << " ** * DEREGISTERING TIMELINE CLIP: " << clipId;
Q_ASSERT(m_registeredClips.count(clipId) > 0);
if (m_hasAudio && audioClip) {
m_audioCount--;
......@@ -1689,13 +1721,14 @@ void ProjectClip::deregisterTimelineClip(int clipId, bool audioClip)
m_audioProducers.erase(clipId);
}
setRefCount(uint(m_registeredClips.size()), m_audioCount);
emit registeredClipChanged();
}
QList<int> ProjectClip::timelineInstances() const
{
QList<int> ids;
for (const auto &m_registeredClip : m_registeredClips) {
ids.push_back(m_registeredClip.first);
for (const auto &registeredClip : m_registeredClips) {
ids.push_back(registeredClip.first);
}
return ids;
}
......
......@@ -16,6 +16,7 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#include <QFuture>
#include <QMutex>
#include <QTimer>
#include <memory>
class ClipPropertiesController;
......@@ -231,6 +232,8 @@ public:
int getRecordTime();
/** @brief Return maximum audio level for a stream. */
int getAudioMax(int stream);
/** @brief Refresh zones of insertion in timeline. */
void refreshBounds();
protected:
friend class ClipModel;
......@@ -287,6 +290,8 @@ public slots:
bool setProducer(std::shared_ptr<Mlt::Producer> producer);
void importJsonMarkers(const QString &json);
/** @brief Refresh zones of insertion in timeline. */
void checkClipBounds();
private:
/** @brief Generate and store file hash if not available. */
......@@ -303,6 +308,7 @@ private:
std::map<int, std::weak_ptr<TimelineModel>> m_registeredClips;
uint m_audioCount;
QTimer m_boundaryTimer;
/** @brief the following holds a producer for each audio clip in the timeline
* keys are the id of the clips in the timeline, values are their values */
......@@ -321,6 +327,8 @@ signals:
void loadPropertiesPanel();
void audioThumbReady();
void updateStreamInfo(int ix);
void boundsChanged(QVector <QPoint>bounds);
void registeredClipChanged();
};
#endif
......@@ -360,6 +360,8 @@ signals:
void monitorProfileUpdated();
/** @brief Color theme changed, process refresh */
void updatePalette();
/** @brief Emitted when a clip is resized (to handle clip monitor inserted zones) */
void clipInstanceResized(const QString &binId);
};
#endif
......@@ -241,6 +241,12 @@ Monitor::Monitor(Kdenlive::MonitorId id, MonitorManager *manager, QWidget *paren
m_recManager = new RecManager(this);
connect(m_recManager, &RecManager::warningMessage, this, &Monitor::warningMessage);
connect(m_recManager, &RecManager::addClipToProject, this, &Monitor::addClipToProject);
// Show timeline clip usage
connect(pCore.get(), &Core::clipInstanceResized, this, [this](const QString &binId) {
if (m_controller && activeClipId() == binId) {
m_controller->checkClipBounds();
}
});
m_toolbar->addAction(manager->getAction(QStringLiteral("insert_project_tree")));
m_toolbar->setToolTip(i18n("Insert Zone to Project Bin"));
......@@ -1650,6 +1656,10 @@ void Monitor::slotOpenClip(const std::shared_ptr<ProjectClip> &controller, int i
SLOT(checkOverlay()));
disconnect(m_controller->getMarkerModel().get(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(checkOverlay()));
disconnect(m_controller->getMarkerModel().get(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(checkOverlay()));
if (m_controller->hasLimitedDuration()) {
disconnect(m_controller.get(), &ProjectClip::boundsChanged, m_glMonitor->getControllerProxy(), &MonitorProxy::updateClipBounds);
disconnect(m_controller.get(), &ProjectClip::registeredClipChanged, m_controller.get(), &ProjectClip::checkClipBounds);
}
}
disconnect(this, &Monitor::seekPosition, this, &Monitor::seekRemap);
m_controller = controller;
......@@ -1704,6 +1714,10 @@ void Monitor::slotOpenClip(const std::shared_ptr<ProjectClip> &controller, int i
//m_audioChannels->menuAction()->setVisible(false);
}
connect(m_controller.get(), &ProjectClip::audioThumbReady, this, &Monitor::prepareAudioThumb);
if (m_controller->hasLimitedDuration()) {
connect(m_controller.get(), &ProjectClip::boundsChanged, m_glMonitor->getControllerProxy(), &MonitorProxy::updateClipBounds);
connect(m_controller.get(), &ProjectClip::registeredClipChanged, m_controller.get(), &ProjectClip::checkClipBounds);
}
connect(m_controller->getMarkerModel().get(), SIGNAL(dataChanged(QModelIndex,QModelIndex,QVector<int>)), this,
SLOT(checkOverlay()));
connect(m_controller->getMarkerModel().get(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(checkOverlay()));
......
......@@ -32,6 +32,7 @@ MonitorProxy::MonitorProxy(GLWidget *parent)
, m_clipId(-1)
, m_seekFinished(true)
, m_td(nullptr)
, m_boundsCount(0)
{
}
......@@ -198,6 +199,9 @@ void MonitorProxy::resetZone()
{
m_zoneIn = 0;
m_zoneOut = -1;
m_clipBounds = {};
m_boundsCount = 0;
emit clipBoundsChanged();
}
double MonitorProxy::fps() const
......@@ -433,3 +437,21 @@ QByteArray MonitorProxy::getUuid() const
{
return QUuid::createUuid().toByteArray();
}
void MonitorProxy::updateClipBounds(QVector <QPoint>bounds)
{
if (bounds == m_clipBounds) {
// Enforce refresh, in/out points may have changed
m_boundsCount = 0;
emit clipBoundsChanged();
}
m_clipBounds = bounds;
m_boundsCount = bounds.size();
emit clipBoundsChanged();
}
const QPoint MonitorProxy::clipBoundary(int ix)
{
return m_clipBounds.at(ix);
}
......@@ -37,6 +37,7 @@ class MonitorProxy : public QObject
Q_PROPERTY(QString trimmingTC2 READ trimmingTC2 NOTIFY trimmingTC2Changed)
Q_PROPERTY(QList <int> audioStreams MEMBER m_audioStreams NOTIFY audioThumbChanged)
Q_PROPERTY(QList <int> audioChannels MEMBER m_audioChannels NOTIFY audioThumbChanged)
Q_PROPERTY(int clipBounds MEMBER m_boundsCount NOTIFY clipBoundsChanged)
Q_PROPERTY(int overlayType READ overlayType WRITE setOverlayType NOTIFY overlayTypeChanged)
Q_PROPERTY(double speed MEMBER m_speed NOTIFY speedChanged)
Q_PROPERTY(QColor thumbColor1 READ thumbColor1 NOTIFY colorsChanged)
......@@ -76,6 +77,7 @@ public:
Q_INVOKABLE QColor thumbColor1() const;
Q_INVOKABLE QColor thumbColor2() const;
Q_INVOKABLE QByteArray getUuid() const;
Q_INVOKABLE const QPoint clipBoundary(int ix);
bool audioThumbFormat() const;
bool audioThumbNormalize() const;
void positionFromConsumer(int pos, bool playing);
......@@ -152,6 +154,7 @@ signals:
void trimmingTC1Changed();
void trimmingTC2Changed();
void speedChanged();
void clipBoundsChanged();
private:
GLWidget *q;
......@@ -173,6 +176,11 @@ private:
TimecodeDisplay *m_td;
int m_trimmingFrames1;
int m_trimmingFrames2;
QVector <QPoint> m_clipBounds;
int m_boundsCount;
public slots:
void updateClipBounds(QVector <QPoint>bounds);
};
#endif
......@@ -605,5 +605,18 @@ Item {
bottom: root.bottom
}
height: controller.rulerHeight
Repeater {
model:controller.clipBounds
anchors.fill: parent
Rectangle {
anchors.top: parent.top
anchors.topMargin: 1
property point bd: controller.clipBoundary(model.index)
x: bd.x * root.timeScale - (audioThumb.width/root.zoomFactor * root.zoomStart)
width: bd.y * root.timeScale
height: 2
color: 'goldenrod'
}
}
}
}
......@@ -248,6 +248,9 @@ bool ClipModel::requestResize(int size, bool right, Fun &undo, Fun &redo, bool l
}
}
}
if (logUndo && !m_endlessResize) {
emit pCore->clipInstanceResized(m_binClipId);
}
}
return true;
}
......@@ -293,6 +296,9 @@ bool ClipModel::requestResize(int size, bool right, Fun &undo, Fun &redo, bool l
}
}
}
if (logUndo && !m_endlessResize) {
emit pCore->clipInstanceResized(m_binClipId);
}
}
return true;
}
......
......@@ -298,6 +298,14 @@ int TimelineModel::getClipIn(int clipId) const
return clip->getIn();
}
QPoint TimelineModel::getClipInDuration(int clipId) const
{
READ_LOCK();
Q_ASSERT(m_allClips.count(clipId) > 0);
const auto clip = m_allClips.at(clipId);
return {clip->getIn(), clip->getPlaytime()};
}
PlaylistState::ClipState TimelineModel::getClipState(int clipId) const
{
READ_LOCK();
......@@ -4181,6 +4189,7 @@ void TimelineModel::registerClip(const std::shared_ptr<ClipModel> &clip, bool re
int id = clip->getId();
Q_ASSERT(m_allClips.count(id) == 0);
m_allClips[id] = clip;
qDebug()<<"::: REGISTERING CLIP TO BIN:::::\n::::::::::::::::::::::";
clip->registerClipToBin(clip->getProducer(), registerProducer);
m_groups->createGroupItem(id);
clip->setTimelineEffectsEnabled(m_timelineEffectsEnabled);
......
......@@ -280,6 +280,10 @@ public:
@param clipId Id of the clip to test
*/
int getClipIn(int clipId) const;
/** @brief Returns the in and playtime of a clip
@param clipId Id of the clip to test
*/
QPoint getClipInDuration(int clipId) const;
/** @brief Returns the clip state (audio/video only)
*/
......
Supports Markdown
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