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

Fix timeline clip menu for Qt < 5.9

Add context menu to add a favorite effet / composition to a clip
parent 28d80503
......@@ -49,6 +49,9 @@ std::shared_ptr<EffectTreeModel> EffectTreeModel::construct(const QString &categ
QHash<QString, std::shared_ptr<TreeItem>> effectCategory; // category in which each effect should land.
std::shared_ptr<TreeItem> miscCategory = nullptr;
std::shared_ptr<TreeItem> audioCategory = nullptr;
std::shared_ptr<TreeItem> customCategory = nullptr;
// We parse category file
if (!categoryFile.isEmpty()) {
QDomDocument doc;
......@@ -69,13 +72,17 @@ std::shared_ptr<EffectTreeModel> EffectTreeModel::construct(const QString &categ
effectCategory[effect] = groupItem;
}
}
// We also create "Misc", "Audio" and "Custom" categories
miscCategory = self->rootItem->appendChild(QList<QVariant>{i18n("Misc"), QStringLiteral("root")});
audioCategory = self->rootItem->appendChild(QList<QVariant>{i18n("Audio"), QStringLiteral("root")});
customCategory = self->rootItem->appendChild(QList<QVariant>{i18n("Custom"), QStringLiteral("root")});
} else {
// Flat view
miscCategory = self->rootItem;
audioCategory = self->rootItem;
customCategory = self->rootItem;
}
// We also create "Misc", "Audio" and "Custom" categories
auto miscCategory = self->rootItem->appendChild(QList<QVariant>{i18n("Misc"), QStringLiteral("root")});
auto audioCategory = self->rootItem->appendChild(QList<QVariant>{i18n("Audio"), QStringLiteral("root")});
auto customCategory = self->rootItem->appendChild(QList<QVariant>{i18n("Custom"), QStringLiteral("root")});
// We parse effects
auto allEffects = EffectsRepository::get()->getNames();
for (const auto &effect : allEffects) {
......
import QtQuick 2.6
import QtQuick.Controls 2.2
ComboBox {
}
......@@ -237,13 +237,13 @@ Rectangle {
drag.target = clipRoot
} else if (mouse.button == Qt.RightButton) {
drag.target = undefined
clipMenu.clipId = clipRoot.clipId
clipMenu.clipStatus = clipRoot.clipStatus
clipMenu.grouped = clipRoot.grouped
clipMenu.trackId = clipRoot.trackId
clipMenu.canBeAudio = clipRoot.canBeAudio
clipMenu.canBeVideo = clipRoot.canBeVideo
clipMenu.popup()
clipMenu.item.clipId = clipRoot.clipId
clipMenu.item.clipStatus = clipRoot.clipStatus
clipMenu.item.grouped = clipRoot.grouped
clipMenu.item.trackId = clipRoot.trackId
clipMenu.item.canBeAudio = clipRoot.canBeAudio
clipMenu.item.canBeVideo = clipRoot.canBeVideo
clipMenu.item.popup()
}
}
onPositionChanged: {
......
......@@ -84,4 +84,18 @@ Menu {
text: clipStatus != ClipState.Disabled ? i18n('Disable clip') : i18n('Enable clip')
onTriggered: timeline.switchEnableState(clipId)
}
AssetMenu {
title: i18n('Insert an effect...')
menuModel: effectModel
onAssetSelected: {
timeline.addEffectToClip(assetId, clipId)
}
}
AssetMenu {
title: i18n('Insert a composition...')
menuModel: transitionModel
onAssetSelected: {
timeline.addCompositionToClip(assetId, clipId)
}
}
}
import QtQuick 2.6
import QtQuick.Controls 1.4
import com.enums 1.0
Menu {
id: clipMenu
property int clipId
property int clipStatus
property int trackId
property bool grouped
property bool canBeAudio
property bool canBeVideo
MenuItem {
text: i18n('Copy')
onTriggered: root.copiedClip = clipId
}
MenuItem {
visible: !grouped && timeline.selection.length > 1
text: i18n('Group')
onTriggered: timeline.triggerAction('group_clip')
}
MenuItem {
visible: grouped
text: i18n('Ungroup')
onTriggered: timeline.unGroupSelection(clipId)
}
MenuItem {
text: i18n('Edit Duration')
onTriggered: {
clipMenu.close()
timeline.editItemDuration(clipId)
}
}
MenuItem {
visible: root.copiedClip != -1 && root.copiedClip != clipId
text: i18n('Paste Effects')
onTriggered: timeline.pasteEffects(clipId, root.copiedClip)
}
MenuSeparator {
visible: true
}
MenuItem {
text: i18n('Split Audio')
onTriggered: timeline.splitAudio(clipId)
visible: !grouped && canBeAudio && clipStatus == ClipState.VideoOnly
}
MenuItem {
text: i18n('Split Video')
onTriggered: timeline.splitVideo(clipId)
visible: !grouped && canBeVideo && clipStatus == ClipState.AudioOnly
}
MenuItem {
text: i18n('Remove')
onTriggered: timeline.triggerAction('delete_timeline_clip')
}
MenuItem {
visible: true
text: i18n('Extract')
onTriggered: timeline.extract(clipId)
}
MenuSeparator {
visible: true
}
MenuItem {
visible: true
text: i18n('Change Speed')
onTriggered: {
clipMenu.close()
timeline.changeItemSpeed(clipId, -1)
}
}
MenuItem {
text: i18n('Clip in Project Bin')
onTriggered: timeline.triggerAction('clip_in_project_tree')
}
MenuItem {
visible: true
text: i18n('Split At Playhead')
onTriggered: timeline.triggerAction('cut_timeline_clip')
}
MenuItem {
visible: true
text: clipStatus != ClipState.Disabled ? i18n('Disable clip') : i18n('Enable clip')
onTriggered: timeline.switchEnableState(clipId)
}
AssetMenu {
title: i18n('Insert an effect...')
menuModel: effectModel
onAssetSelected: {
timeline.addEffectToClip(assetId, clipId)
}
}
AssetMenu {
title: i18n('Insert a composition...')
menuModel: transitionModel
onAssetSelected: {
timeline.addCompositionToClip(assetId, clipId)
}
}
}
......@@ -14,6 +14,7 @@ Rectangle {
SystemPalette { id: activePalette }
color: activePalette.window
property bool validMenu: false
signal clipClicked()
signal mousePosChanged(int position)
......@@ -22,8 +23,13 @@ Rectangle {
id: fontMetrics
font.family: "Arial"
}
ClipMenu {
Loader {
source: 'CheckQuickVersion.qml'
property bool validMenu: item.editable == false
id: clipMenu
onLoaded: {
source = validMenu ? 'ClipMenu.qml' : 'ClipMenuOld.qml'
}
}
CompositionMenu {
id: compositionMenu
......
......@@ -1444,6 +1444,20 @@ void TimelineController::switchEnableState(int clipId)
TimelineFunctions::switchEnableState(m_model, clipId);
}
void TimelineController::addCompositionToClip(const QString &assetId, int clipId)
{
int position = m_model->getItemPosition(clipId);
int duration = m_model->getItemPlaytime(clipId);
int track = m_model->getItemTrackId(clipId);
int id;
m_model->requestCompositionInsertion(assetId, track, position, duration, nullptr, id, true);
}
void TimelineController::addEffectToClip(const QString &assetId, int clipId)
{
m_model->addClipEffect(clipId, assetId);
}
bool TimelineController::splitAV()
{
int cid = m_selection.selectedItems.first();
......
......@@ -264,6 +264,8 @@ public:
/* @brief If clip is enabled, disable, otherwise enable
*/
Q_INVOKABLE void switchEnableState(int clipId);
Q_INVOKABLE void addCompositionToClip(const QString &assetId, int clipId);
Q_INVOKABLE void addEffectToClip(const QString &assetId, int clipId);
Q_INVOKABLE void requestClipCut(int clipId, int position);
......
......@@ -22,7 +22,6 @@
#include "timelinewidget.h"
#include "../model/builders/meltBuilder.hpp"
#include "assets/keyframes/model/keyframemodel.hpp"
#include "transitions/transitionlist/model/transitionfilter.hpp"
#include "assets/model/assetparametermodel.hpp"
#include "core.h"
#include "doc/docundostack.hpp"
......@@ -35,7 +34,9 @@
#include "qmltypes/thumbnailprovider.h"
#include "timelinecontroller.h"
#include "transitions/transitionlist/model/transitiontreemodel.hpp"
#include "transitions/transitionlist/model/transitionfilter.hpp"
#include "effects/effectlist/model/effecttreemodel.hpp"
#include "effects/effectlist/model/effectfilter.hpp"
#include "utils/clipboardproxy.hpp"
#include <KDeclarative/KDeclarative>
......@@ -63,12 +64,21 @@ TimelineWidget::TimelineWidget(QWidget *parent)
#endif
registerTimelineItems();
// Build transition model for context menu
m_transitionModel = TransitionTreeModel::construct(true, this);
m_transitionProxyModel.reset(new TransitionFilter(this));
static_cast<TransitionFilter *>(m_transitionProxyModel.get())->setFilterType(true, TransitionType::Favorites);
static_cast<TransitionFilter *>(m_transitionProxyModel.get())->setFilterType(true, TransitionType::Favorites);
m_transitionProxyModel->setSourceModel(m_transitionModel.get());
m_transitionProxyModel->setSortRole(AssetTreeModel::NameRole);
m_transitionProxyModel->sort(0, Qt::AscendingOrder);
// Build effects model for context menu
m_effectsModel = EffectTreeModel::construct(QStringLiteral(), this);
m_effectsProxyModel.reset(new EffectFilter(this));
static_cast<EffectFilter *>(m_effectsProxyModel.get())->setFilterType(true, EffectType::Favorites);
m_effectsProxyModel->setSourceModel(m_effectsModel.get());
m_effectsProxyModel->setSortRole(AssetTreeModel::NameRole);
m_effectsProxyModel->sort(0, Qt::AscendingOrder);
m_proxy = new TimelineController(this);
connect(m_proxy, &TimelineController::zoneMoved, this, &TimelineWidget::zoneMoved);
setResizeMode(QQuickWidget::SizeRootObjectToView);
......@@ -96,6 +106,7 @@ void TimelineWidget::setModel(std::shared_ptr<TimelineItemModel> model)
rootContext()->setContextProperty("controller", model.get());
rootContext()->setContextProperty("timeline", m_proxy);
rootContext()->setContextProperty("transitionModel", m_transitionProxyModel.get());
rootContext()->setContextProperty("effectModel", m_effectsProxyModel.get());
rootContext()->setContextProperty("guidesModel", pCore->projectManager()->current()->getGuideModel().get());
rootContext()->setContextProperty("clipboard", new ClipboardProxy(this));
setSource(QUrl(QStringLiteral("qrc:/qml/timeline.qml")));
......
......@@ -63,6 +63,8 @@ private:
static const int comboScale[];
std::shared_ptr<AssetTreeModel> m_transitionModel;
std::unique_ptr<AssetFilter> m_transitionProxyModel;
std::shared_ptr<AssetTreeModel> m_effectsModel;
std::unique_ptr<AssetFilter> m_effectsProxyModel;
signals:
void focusProjectMonitor();
......
......@@ -28,6 +28,8 @@
<file alias="KeyframeView.qml">timeline2/view/qml/KeyframeView.qml</file>
<file alias="Composition.qml">timeline2/view/qml/Composition.qml</file>
<file alias="ClipMenu.qml">timeline2/view/qml/ClipMenu.qml</file>
<file alias="ClipMenuOld.qml">timeline2/view/qml/ClipMenuOld.qml</file>
<file alias="CheckQuickVersion.qml">timeline2/view/qml/CheckQuickVersion.qml</file>
<file alias="CompositionMenu.qml">timeline2/view/qml/CompositionMenu.qml</file>
<file alias="PulsingAnimation.qml">timeline2/view/qml/PulsingAnimation.qml</file>
<file alias="CornerSelectionShadow.qml">timeline2/view/qml/CornerSelectionShadow.qml</file>
......
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