Cleanup composition switch option, initial prepare for multistream audio

parent 628d4784
Pipeline #9437 failed with stage
in 3 minutes and 17 seconds
......@@ -20,6 +20,7 @@
***************************************************************************/
#include "xml/xml.hpp"
#include "kdenlivesettings.h"
#include <QDir>
#include <QFile>
#include <QStandardPaths>
......@@ -273,6 +274,10 @@ template <typename AssetType> QVector<QPair<QString, QString>> AbstractAssetsRep
QVector<QPair<QString, QString>> res;
res.reserve((int)m_assets.size());
for (const auto &asset : m_assets) {
if (!KdenliveSettings::gpu_accel() && asset.first.contains(QLatin1String("movit."))) {
// Hide GPU effects/compositions when movit disabled
continue;
}
res.push_back({asset.first, asset.second.name});
}
std::sort(res.begin(), res.end(), [](const QPair<QString, QString> &a, const QPair<QString, QString> &b) { return a.second < b.second; });
......
......@@ -41,7 +41,8 @@
#include <QToolButton>
#include <QVBoxLayout>
#include <QScrollArea>
#include <QMenu>
#include <QComboBox>
#include <QFontDatabase>
#include <klocalizedstring.h>
AssetPanel::AssetPanel(QWidget *parent)
......@@ -58,25 +59,20 @@ AssetPanel::AssetPanel(QWidget *parent)
QSize iconSize(size, size);
buttonToolbar->setIconSize(iconSize);
// Edit composition button
m_switchCompoButton = new QToolButton(this);
QMenu *compoMenu = new QMenu(this);
m_switchCompoButton = new QComboBox(this);
m_switchCompoButton->setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
auto allTransitions = TransitionsRepository::get()->getNames();
for (const auto &transition : allTransitions) {
auto *transAction = new QAction(transition.second, this);
transAction->setData(transition.first);
transAction->setIconVisibleInMenu(false);
compoMenu->addAction(transAction);
m_switchCompoButton->addItem(transition.second, transition.first);
}
connect(compoMenu, &QMenu::triggered, [&](QAction *ac) {
connect(m_switchCompoButton, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), [&]() {
if (m_transitionWidget->stackOwner().first == ObjectType::TimelineComposition) {
emit switchCurrentComposition(m_transitionWidget->stackOwner().second, ac->data().toString());
emit switchCurrentComposition(m_transitionWidget->stackOwner().second, m_switchCompoButton->currentData().toString());
}
});
m_switchCompoButton->setMenu(compoMenu);
m_switchCompoButton->setPopupMode(QToolButton::InstantPopup);
m_switchCompoButton->setIcon(QIcon::fromTheme(QStringLiteral("go-down")));
m_switchCompoButton->setToolTip(i18n("Change composition type"));
buttonToolbar->addWidget(m_switchCompoButton);
m_switchAction = buttonToolbar->addWidget(m_switchCompoButton);
m_switchAction->setVisible(false);
// spacer
QWidget *empty = new QWidget();
......@@ -150,10 +146,11 @@ void AssetPanel::showTransition(int tid, const std::shared_ptr<AssetParameterMod
return;
}
clear();
m_switchCompoButton->setVisible(true);
QString transitionId = transitionModel->getAssetId();
m_switchCompoButton->setCurrentIndex(m_switchCompoButton->findData(transitionId));
m_switchAction->setVisible(true);
QString transitionName = TransitionsRepository::get()->getName(transitionId);
m_assetTitle->setText(i18n("%1 properties", i18n(transitionName.toUtf8().data())));
m_assetTitle->setText(i18n("Properties for"));
m_transitionWidget->setVisible(true);
m_timelineButton->setVisible(true);
m_enableStackButton->setVisible(false);
......@@ -238,7 +235,7 @@ void AssetPanel::clearAssetPanel(int itemId)
void AssetPanel::clear()
{
m_switchCompoButton->setVisible(false);
m_switchAction->setVisible(false);
m_transitionWidget->setVisible(false);
m_transitionWidget->unsetModel();
m_effectStackWidget->setVisible(false);
......
......@@ -31,6 +31,7 @@
class KSqueezedTextLabel;
class KDualAction;
class QToolButton;
class QComboBox;
/** @brief This class is the widget that provides interaction with the asset currently selected.
That is, it either displays an effectStack or the parameters of a transition
......@@ -82,7 +83,8 @@ protected:
private:
QToolButton *m_switchBuiltStack;
QToolButton *m_switchCompoButton;
QComboBox *m_switchCompoButton;
QAction *m_switchAction;
KDualAction *m_splitButton;
KDualAction *m_enableStackButton;
KDualAction *m_timelineButton;
......
......@@ -1803,7 +1803,7 @@ void Bin::showClipProperties(const std::shared_ptr<ProjectClip> &clip, bool forc
}
m_propertiesPanel->setProperty("clipId", QString());
m_propertiesPanel->setEnabled(false);
emit setupTargets(false, false);
emit setupTargets(false, {});
return;
}
m_propertiesPanel->setEnabled(true);
......@@ -1818,7 +1818,7 @@ void Bin::showClipProperties(const std::shared_ptr<ProjectClip> &clip, bool forc
}
m_propertiesPanel->setProperty("clipId", clip->AbstractProjectItem::clipId());
// Setup timeline targets
emit setupTargets(clip->hasVideo(), clip->hasAudio());
emit setupTargets(clip->hasVideo(), clip->audioStreams());
auto *lay = static_cast<QVBoxLayout *>(m_propertiesPanel->layout());
if (lay == nullptr) {
lay = new QVBoxLayout(m_propertiesPanel);
......
......@@ -472,7 +472,7 @@ signals:
/** @brief A clip was updated, request panel update. */
void refreshPanel(const QString &id);
/** @brief Upon selection, activate timeline target tracks. */
void setupTargets(bool hasVideo, bool hasAudio);
void setupTargets(bool hasVideo, QList <int> audioStreams);
};
#endif
......@@ -89,9 +89,6 @@ std::shared_ptr<EffectTreeModel> EffectTreeModel::construct(const QString &categ
auto allEffects = EffectsRepository::get()->getNames();
QString favCategory = QStringLiteral("kdenlive:favorites");
for (const auto &effect : allEffects) {
if (!KdenliveSettings::gpu_accel() && effect.first.contains(QLatin1String("movit."))) {
continue;
}
auto targetCategory = miscCategory;
EffectType type = EffectsRepository::get()->getType(effect.first);
if (effectCategory.contains(effect.first)) {
......
......@@ -62,9 +62,9 @@ int AudioStreamInfo::channels() const
return m_channels;
}
int AudioStreamInfo::streams() const
QList <int> AudioStreamInfo::streams() const
{
return m_audioStreams.count();
return m_audioStreams;
}
int AudioStreamInfo::bitrate() const
......
......@@ -28,7 +28,7 @@ public:
int samplingRate() const;
int channels() const;
int streams() const;
QList <int> streams() const;
int bitrate() const;
const QString &samplingFormat() const;
int audio_index() const;
......
......@@ -264,8 +264,8 @@ void MainWindow::init()
connect(m_clipMonitor, &Monitor::seekToNextSnap, this, &MainWindow::slotSnapForward);
connect(pCore->bin(), &Bin::findInTimeline, this, &MainWindow::slotClipInTimeline, Qt::DirectConnection);
connect(pCore->bin(), &Bin::setupTargets, this, [&] (bool hasVideo, bool hasAudio) {
getCurrentTimeline()->controller()->setTargetTracks({hasVideo ? getCurrentTimeline()->model()->getFirstVideoTrackIndex() : -1, hasAudio ? getCurrentTimeline()->model()->getFirstAudioTrackIndex() : -1});
connect(pCore->bin(), &Bin::setupTargets, this, [&] (bool hasVideo, QList <int> audioStreams) {
getCurrentTimeline()->controller()->setTargetTracks(hasVideo, audioStreams);
}
);
......
......@@ -1037,3 +1037,19 @@ void ClipController::refreshAudioInfo()
m_audioInfo->setAudioIndex(m_masterProducer, m_properties->get_int("audio_index"));
}
}
QList <int> ClipController::audioStreams() const
{
if (m_audioInfo) {
return m_audioInfo->streams();
}
return {};
}
int ClipController::audioStreamsCount() const
{
if (m_audioInfo) {
return m_audioInfo->streams().count();
}
return 0;
}
......@@ -204,6 +204,11 @@ public:
/** @brief Append an effect to this producer's effect list */
bool addEffect(const QString &effectId);
/** @brief Returns the list of audio streams indexes for this clip */
QList <int> audioStreams() const;
/** @brief Returns the count of audio streams for this clip */
int audioStreamsCount() const;
protected:
virtual void emitProducerChanged(const QString & /*unused*/, const std::shared_ptr<Mlt::Producer> & /*unused*/){};
virtual void connectEffectStack(){};
......
......@@ -1036,7 +1036,7 @@ void ClipPropertiesController::fillProperties()
propertyMap.append({i18n("Colorspace"), ProfileRepository::getColorspaceDescription(colorspace)});
}
if (default_audio > -1) {
propertyMap.append({i18n("Audio streams"), QString::number(m_controller->audioInfo()->streams())});
propertyMap.append({i18n("Audio streams"), QString::number(m_controller->audioStreamsCount())});
QString codecInfo = QString("meta.media.%1.codec.").arg(default_audio);
QString property = codecInfo + QStringLiteral("long_name");
......
......@@ -3542,12 +3542,16 @@ void TimelineModel::switchComposition(int cid, const QString &compoId)
int duration = compo->getPlaytime();
int currentTrack = compo->getCurrentTrackId();
int a_track = compo->getATrack();
int forcedTrack = compo->getForcedTrack();
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool res = requestCompositionDeletion(cid, undo, redo);
int newId;
res = res && requestCompositionInsertion(compoId, currentTrack, a_track, currentPos, duration, nullptr, newId, undo, redo);
if (res) {
if (forcedTrack > -1 && isComposition(newId)) {
m_allCompositions[newId]->setForceTrack(true);
}
Fun local_redo = [newId, this]() {
requestSetSelection({newId});
return true;
......
......@@ -107,17 +107,37 @@ void TimelineController::setModel(std::shared_ptr<TimelineItemModel> model)
connect(m_model.get(), &TimelineModel::selectionChanged, this, &TimelineController::selectionChanged);
}
void TimelineController::setTargetTracks(QPair<int, int> targets)
{
m_hasVideoTarget = targets.first >= 0;
m_hasAudioTarget = targets.second >= 0;
void TimelineController::setTargetTracks(bool hasVideo, QList <int> audioTargets)
{
int videoTrack = -1;
QList <int> audioTracks;
m_hasVideoTarget = hasVideo;
m_hasAudioTarget = !audioTargets.isEmpty();
if (m_hasVideoTarget) {
videoTrack = m_model->getFirstVideoTrackIndex();
}
if (m_hasAudioTarget) {
QList <int> tracks;
auto it = m_model->m_allTracks.cbegin();
while (it != m_model->m_allTracks.cend()) {
if ((*it)->isAudioTrack()) {
tracks << (*it)->getId();
}
++it;
}
int i = 0;
while (i < audioTargets.size() && !tracks.isEmpty()) {
audioTracks << tracks.takeLast();
i++;
}
}
emit hasAudioTargetChanged();
emit hasVideoTargetChanged();
if (m_videoTargetActive) {
setVideoTarget(m_hasVideoTarget && (m_lastVideoTarget > -1) ? m_lastVideoTarget : targets.first);
setVideoTarget(m_hasVideoTarget && (m_lastVideoTarget > -1) ? m_lastVideoTarget : videoTrack);
}
if (m_audioTargetActive) {
setAudioTarget(m_hasAudioTarget && (m_lastAudioTarget > -1) ? m_lastAudioTarget : targets.second);
setIntAudioTarget((m_hasAudioTarget && (m_lastAudioTarget.size() == audioTargets.size())) ? m_lastAudioTarget : audioTracks);
}
}
......@@ -578,8 +598,8 @@ void TimelineController::deleteTrack(int tid)
if (m_model->m_videoTarget == selectedTrackIx) {
setVideoTarget(-1);
}
if (m_lastAudioTarget == selectedTrackIx) {
m_lastAudioTarget = -1;
if (m_lastAudioTarget.contains(selectedTrackIx)) {
m_lastAudioTarget.removeAll(selectedTrackIx);
emit lastAudioTargetChanged();
}
if (m_lastVideoTarget == selectedTrackIx) {
......@@ -936,6 +956,16 @@ void TimelineController::setAudioTarget(int track)
emit audioTargetChanged();
}
void TimelineController::setIntAudioTarget(QList <int> tracks)
{
if ((!tracks.isEmpty() && !m_model->isTrack(tracks.first())) || !m_hasAudioTarget) {
return;
}
qDebug()<<"/// GOT AUDIO TRACKS: "<<tracks;
m_model->m_audioTarget = tracks.isEmpty() ? -1 : tracks.first();
emit audioTargetChanged();
}
void TimelineController::setVideoTarget(int track)
{
if ((track > -1 && !m_model->isTrack(track)) || !m_hasVideoTarget) {
......@@ -2617,7 +2647,7 @@ void TimelineController::updateVideoTarget()
void TimelineController::updateAudioTarget()
{
if (audioTarget() > -1) {
m_lastAudioTarget = audioTarget();
m_lastAudioTarget = {audioTarget()};
m_audioTargetActive = true;
emit lastAudioTargetChanged();
} else {
......
......@@ -68,7 +68,7 @@ class TimelineController : public QObject
Q_PROPERTY(int audioTarget READ audioTarget WRITE setAudioTarget NOTIFY audioTargetChanged)
Q_PROPERTY(int videoTarget READ videoTarget WRITE setVideoTarget NOTIFY videoTargetChanged)
Q_PROPERTY(int lastAudioTarget MEMBER m_lastAudioTarget NOTIFY lastAudioTargetChanged)
//Q_PROPERTY(int lastAudioTarget MEMBER m_lastAudioTarget NOTIFY lastAudioTargetChanged)
Q_PROPERTY(int lastVideoTarget MEMBER m_lastVideoTarget NOTIFY lastVideoTargetChanged)
Q_PROPERTY(bool hasAudioTarget READ hasAudioTarget NOTIFY hasAudioTargetChanged)
......@@ -459,7 +459,7 @@ public:
/** @brief timeline preview params changed, reset */
void resetPreview();
/** @brief Set target tracks (video, audio) */
void setTargetTracks(QPair<int, int> targets);
void setTargetTracks(bool hasVideo, QList <int> audioTargets);
/** @brief Return asset's display name from it's id (effect or composition) */
Q_INVOKABLE const QString getAssetName(const QString &assetId, bool isTransition);
/** @brief Set keyboard grabbing on current selection */
......@@ -475,6 +475,7 @@ public slots:
void resetView();
Q_INVOKABLE void setSeekPosition(int position);
Q_INVOKABLE void setAudioTarget(int track);
void setIntAudioTarget(QList <int> tracks);
Q_INVOKABLE void setVideoTarget(int track);
Q_INVOKABLE void setActiveTrack(int track);
void onSeeked(int position);
......@@ -515,7 +516,7 @@ private:
bool m_hasAudioTarget {false};
bool m_hasVideoTarget {false};
int m_lastVideoTarget {-1};
int m_lastAudioTarget {-1};
QList <int> m_lastAudioTarget;
bool m_videoTargetActive {true};
bool m_audioTargetActive {true};
QPair<int, int> m_recordStart;
......
......@@ -49,10 +49,6 @@ std::shared_ptr<TransitionTreeModel> TransitionTreeModel::construct(bool flat, Q
// We parse transitions
auto allTransitions = TransitionsRepository::get()->getNames();
for (const auto &transition : allTransitions) {
if (!KdenliveSettings::gpu_accel() && transition.first.contains(QLatin1String("movit."))) {
// Hide GPU compositions when movit disabled
continue;
}
std::shared_ptr<TreeItem> targetCategory = compoCategory;
TransitionType type = TransitionsRepository::get()->getType(transition.first);
if (type == TransitionType::AudioTransition || type == TransitionType::VideoTransition) {
......
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