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

Guides list: make it work with keyboard shortcuts, fix group deletion

parent 2cb43162
Pipeline #260691 passed with stage
in 13 minutes and 59 seconds
......@@ -3027,8 +3027,6 @@ void Bin::showClipProperties(const std::shared_ptr<ProjectClip> &clip, bool forc
m_propertiesPanel->setLayout(lay);
}
ClipPropertiesController *panel = clip->buildProperties(m_propertiesPanel);
connect(this, &Bin::deleteMarkers, panel, &ClipPropertiesController::slotDeleteSelectedMarkers);
connect(this, &Bin::selectMarkers, panel, &ClipPropertiesController::slotSelectAllMarkers);
connect(panel, &ClipPropertiesController::updateClipProperties, this, &Bin::slotEditClipCommand);
connect(panel, &ClipPropertiesController::seekToFrame, m_monitor, static_cast<void (Monitor::*)(int)>(&Monitor::slotSeek));
connect(panel, &ClipPropertiesController::editClip, this, &Bin::slotEditClip);
......@@ -4548,20 +4546,6 @@ void Bin::setBinEffectsEnabled(bool enabled, bool refreshMonitor)
void Bin::slotRenameItem()
{
if (!hasFocus() && !m_itemView->hasFocus()) {
QWidget *widget = QApplication::focusWidget();
while ((widget != nullptr) && widget != pCore->window()) {
if (widget == pCore->bin()->clipPropertiesDock()) {
foreach (QWidget *w, m_propertiesPanel->findChildren<ClipPropertiesController *>()) {
static_cast<ClipPropertiesController *>(w)->slotEditMarker();
break;
}
return;
}
widget = widget->parentWidget();
}
return;
}
const QModelIndexList indexes = m_proxyModel->selectionModel()->selection().indexes();
for (const QModelIndex &ix : indexes) {
if (!ix.isValid() || ix.column() != 0) {
......
......@@ -614,9 +614,5 @@ signals:
void setupTargets(bool hasVideo, QMap <int, QString> audioStreams);
/** @brief A drag event ended, inform timeline. */
void processDragEnd();
/** @brief Delete selected markers in clip properties dialog. */
void deleteMarkers();
/** @brief Selected all markers in clip properties dialog. */
void selectMarkers();
void requestBinClose();
};
......@@ -2573,7 +2573,6 @@ void MainWindow::slotDeleteItem()
}
}
if (QApplication::focusWidget() != nullptr && pCore->textEditWidget()->isAncestorOf(QApplication::focusWidget())) {
qDebug() << "===============\nDELETE TEXT BASED ITEM";
pCore->textEditWidget()->deleteItem();
} else {
QWidget *widget = QApplication::focusWidget();
......@@ -2582,8 +2581,8 @@ void MainWindow::slotDeleteItem()
m_assetPanel->deleteCurrentEffect();
return;
}
if (widget == pCore->bin()->clipPropertiesDock()) {
emit pCore->bin()->deleteMarkers();
if (widget == pCore->guidesList()) {
pCore->guidesList()->removeGuide();
return;
}
widget = widget->parentWidget();
......@@ -2799,8 +2798,8 @@ void MainWindow::slotSelectAllTracks()
}
}
}
if (QApplication::focusWidget()->objectName() == QLatin1String("markers_list")) {
emit pCore->bin()->selectMarkers();
if (QApplication::focusWidget()->objectName() == QLatin1String("guides_list")) {
pCore->guidesList()->selectAll();
return;
}
}
......
......@@ -6,7 +6,6 @@ SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
#include "clippropertiescontroller.h"
#include "bin/model/markerlistmodel.hpp"
#include "clipcontroller.h"
#include "core.h"
#include "dialogs/profilesdialog.h"
......@@ -228,7 +227,6 @@ ClipPropertiesController::ClipPropertiesController(ClipController *controller, Q
auto *forcePage = new QScrollArea(this);
auto *forceAudioPage = new QScrollArea(this);
m_propertiesPage = new QWidget(this);
m_markersPage = new QWidget(this);
m_metaPage = new QWidget(this);
m_analysisPage = new QWidget(this);
......@@ -244,33 +242,6 @@ ClipPropertiesController::ClipPropertiesController(ClipController *controller, Q
fillProperties();
m_propertiesPage->setLayout(propsBox);
// Clip markers
auto *mBox = new QVBoxLayout;
m_markerTree = new QTreeView;
m_markerTree->setRootIsDecorated(false);
m_markerTree->setAlternatingRowColors(true);
m_markerTree->setHeaderHidden(true);
m_markerTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
m_markerTree->setObjectName("markers_list");
mBox->addWidget(m_markerTree);
m_sortMarkers = std::make_unique<QSortFilterProxyModel>(this);
m_sortMarkers->setSourceModel(controller->getMarkerModel().get());
m_sortMarkers->setSortRole(MarkerListModel::PosRole);
m_sortMarkers->sort(0, Qt::AscendingOrder);
m_markerTree->setModel(m_sortMarkers.get());
auto *bar = new QToolBar;
bar->addAction(QIcon::fromTheme(QStringLiteral("document-new")), i18n("Add marker…"), this, SLOT(slotAddMarker()));
bar->addAction(QIcon::fromTheme(QStringLiteral("trash-empty")), i18n("Delete marker"), this, SLOT(slotDeleteMarker()));
bar->addAction(QIcon::fromTheme(QStringLiteral("document-edit")), i18n("Edit marker…"), this, SLOT(slotEditMarker()));
bar->addAction(QIcon::fromTheme(QStringLiteral("document-save-as")), i18n("Export markers…"), this, SLOT(slotSaveMarkers()));
bar->addAction(QIcon::fromTheme(QStringLiteral("document-open")), i18n("Import markers…"), this, SLOT(slotLoadMarkers()));
mBox->addWidget(bar);
m_markersPage->setLayout(mBox);
connect(m_markerTree, &QAbstractItemView::activated, this, &ClipPropertiesController::slotSeekToMarker);
connect(m_markerTree, &QAbstractItemView::clicked, this, &ClipPropertiesController::slotSeekToMarker);
connect(m_markerTree, &QAbstractItemView::doubleClicked, this, &ClipPropertiesController::slotEditMarker);
// metadata
auto *m2Box = new QVBoxLayout;
auto *metaTree = new QTreeWidget;
......@@ -1021,7 +992,6 @@ ClipPropertiesController::ClipPropertiesController(ClipController *controller, Q
m_tabWidget->addTab(m_propertiesPage, QString());
m_tabWidget->addTab(forcePage, QString());
m_tabWidget->addTab(forceAudioPage, QString());
m_tabWidget->addTab(m_markersPage, QString());
m_tabWidget->addTab(m_metaPage, QString());
m_tabWidget->addTab(m_analysisPage, QString());
m_tabWidget->setTabIcon(0, QIcon::fromTheme(QStringLiteral("edit-find")));
......@@ -1030,12 +1000,10 @@ ClipPropertiesController::ClipPropertiesController(ClipController *controller, Q
m_tabWidget->setTabToolTip(1, i18n("Properties"));
m_tabWidget->setTabIcon(2, QIcon::fromTheme(QStringLiteral("audio-volume-high")));
m_tabWidget->setTabToolTip(2, i18n("Audio Properties"));
m_tabWidget->setTabIcon(3, QIcon::fromTheme(QStringLiteral("bookmark-new")));
m_tabWidget->setTabToolTip(3, i18n("Markers"));
m_tabWidget->setTabIcon(4, QIcon::fromTheme(QStringLiteral("view-grid")));
m_tabWidget->setTabToolTip(4, i18n("Metadata"));
m_tabWidget->setTabIcon(5, QIcon::fromTheme(QStringLiteral("visibility")));
m_tabWidget->setTabToolTip(5, i18n("Analysis"));
m_tabWidget->setTabIcon(3, QIcon::fromTheme(QStringLiteral("view-grid")));
m_tabWidget->setTabToolTip(3, i18n("Metadata"));
m_tabWidget->setTabIcon(4, QIcon::fromTheme(QStringLiteral("visibility")));
m_tabWidget->setTabToolTip(4, i18n("Analysis"));
m_tabWidget->setCurrentIndex(KdenliveSettings::properties_panel_page());
if (m_type == ClipType::Color) {
m_tabWidget->setTabEnabled(0, false);
......@@ -1412,116 +1380,6 @@ void ClipPropertiesController::fillProperties()
m_propertiesTree->resizeColumnToContents(0);
}
void ClipPropertiesController::slotSeekToMarker()
{
auto markerModel = m_controller->getMarkerModel();
auto current = m_sortMarkers->mapToSource(m_markerTree->currentIndex());
if (!current.isValid()) return;
GenTime pos(markerModel->data(current, MarkerListModel::PosRole).toDouble());
emit seekToFrame(pos.frames(pCore->getCurrentFps()));
}
void ClipPropertiesController::slotEditMarker()
{
auto markerModel = m_controller->getMarkerModel();
auto current = m_sortMarkers->mapToSource(m_markerTree->currentIndex());
if (!current.isValid()) return;
GenTime pos(markerModel->data(current, MarkerListModel::PosRole).toDouble());
markerModel->editMarkerGui(pos, this, false, m_controller);
}
void ClipPropertiesController::slotDeleteMarker()
{
auto markerModel = m_controller->getMarkerModel();
QModelIndexList indexes = m_markerTree->selectionModel()->selectedIndexes();
QModelIndexList mapped;
for (auto &ix : indexes) {
mapped << m_sortMarkers->mapToSource(ix);
}
QList<GenTime> positions;
for (auto &ix : mapped) {
if (ix.isValid()) {
positions << GenTime(markerModel->data(ix, MarkerListModel::PosRole).toDouble());
}
}
if (!positions.isEmpty()) {
Fun undo = []() { return true; };
Fun redo = []() { return true; };
for (GenTime pos : qAsConst(positions)) {
markerModel->removeMarker(pos, undo, redo);
}
pCore->pushUndo(undo, redo, i18n("Delete marker"));
}
}
void ClipPropertiesController::slotAddMarker()
{
auto markerModel = m_controller->getMarkerModel();
GenTime pos(m_controller->originalProducer()->position(), pCore->getCurrentFps());
markerModel->editMarkerGui(pos, this, true, m_controller, true);
}
void ClipPropertiesController::slotSaveMarkers()
{
QScopedPointer<QFileDialog> fd(new QFileDialog(this, i18nc("@title:window", "Save Clip Markers"), pCore->projectManager()->current()->projectDataFolder()));
fd->setMimeTypeFilters({QStringLiteral("application/json"), QStringLiteral("text/plain")});
fd->setFileMode(QFileDialog::AnyFile);
fd->setAcceptMode(QFileDialog::AcceptSave);
if (fd->exec() != QDialog::Accepted) {
return;
}
QStringList selection = fd->selectedFiles();
QString url;
if (!selection.isEmpty()) {
url = selection.first();
}
if (url.isEmpty()) {
return;
}
QFile file(url);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
KMessageBox::error(this, i18n("Cannot open file %1", QUrl::fromLocalFile(url).fileName()));
return;
}
file.write(m_controller->getMarkerModel()->toJson().toUtf8());
file.close();
}
void ClipPropertiesController::slotLoadMarkers()
{
QScopedPointer<QFileDialog> fd(new QFileDialog(this, i18nc("@title:window", "Load Clip Markers"), pCore->projectManager()->current()->projectDataFolder()));
fd->setMimeTypeFilters({QStringLiteral("application/json"), QStringLiteral("text/plain")});
fd->setFileMode(QFileDialog::ExistingFile);
if (fd->exec() != QDialog::Accepted) {
return;
}
QStringList selection = fd->selectedFiles();
QString url;
if (!selection.isEmpty()) {
url = selection.first();
}
if (url.isEmpty()) {
return;
}
QFile file(url);
if (file.size() > 1048576 &&
KMessageBox::warningContinueCancel(this, i18n("Marker file is larger than 1MB, are you sure you want to import ?")) != KMessageBox::Continue) {
// If marker file is larger than 1MB, ask for confirmation
return;
}
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
KMessageBox::error(this, i18n("Cannot open file %1", QUrl::fromLocalFile(url).fileName()));
return;
}
QString fileContent = QString::fromUtf8(file.readAll());
file.close();
bool res = m_controller->getMarkerModel()->importFromJson(fileContent, false);
if (!res) {
KMessageBox::error(this, i18n("An error occurred while parsing the marker file"));
}
}
void ClipPropertiesController::slotFillMeta(QTreeWidget *tree)
{
tree->clear();
......@@ -1728,20 +1586,6 @@ void ClipPropertiesController::activatePage(int ix)
m_tabWidget->setCurrentIndex(ix);
}
void ClipPropertiesController::slotDeleteSelectedMarkers()
{
if (m_tabWidget->currentIndex() == 3) {
slotDeleteMarker();
}
}
void ClipPropertiesController::slotSelectAllMarkers()
{
if (m_tabWidget->currentIndex() == 3) {
m_markerTree->selectAll();
}
}
void ClipPropertiesController::updateStreamInfo(int streamIndex)
{
QStringList effects = m_controller->getAudioStreamEffect(m_activeAudioStreams);
......
......@@ -80,21 +80,13 @@ public slots:
void slotReloadProperties();
void slotFillMeta(QTreeWidget *tree);
void slotFillAnalysisData();
void slotDeleteSelectedMarkers();
void slotSelectAllMarkers();
void updateStreamInfo(int streamIndex);
void slotEditMarker();
private slots:
void slotColorModified(const QColor &newcolor);
void slotDurationChanged(int duration);
void slotEnableForce(int state);
void slotValueChanged(double);
void slotSeekToMarker();
void slotDeleteMarker();
void slotAddMarker();
void slotLoadMarkers();
void slotSaveMarkers();
void slotDeleteAnalysis();
void slotSaveAnalysis();
void slotLoadAnalysis();
......@@ -119,12 +111,9 @@ private:
QList<int> m_videoStreams;
QTreeWidget *m_propertiesTree;
QWidget *m_propertiesPage;
QWidget *m_markersPage;
QWidget *m_metaPage;
QWidget *m_analysisPage;
QComboBox *m_audioStream;
QTreeView *m_markerTree;
std::unique_ptr<QSortFilterProxyModel>m_sortMarkers;
AnalysisTree *m_analysisTree;
QTextEdit *m_textEdit;
QListWidget *m_audioStreamsView;
......
......@@ -59,6 +59,8 @@ GuidesList::GuidesList(QWidget *parent)
connect(guide_edit, &QToolButton::clicked, this, &GuidesList::editGuides);
connect(filter_line, &QLineEdit::textChanged, this, &GuidesList::filterView);
connect(pCore.get(), &Core::updateDefaultMarkerCategory, this, &GuidesList::refreshDefaultCategory);
QAction *a = KStandardAction::renameFile(this, &GuidesList::editGuides, this);
guides_list->addAction(a);
// Settings menu
QMenu *settingsMenu = new QMenu(this);
......@@ -192,14 +194,22 @@ void GuidesList::editGuide(const QModelIndex &ix)
}
}
void GuidesList::selectAll()
{
guides_list->selectAll();
}
void GuidesList::removeGuide()
{
QModelIndexList selection = guides_list->selectionModel()->selectedIndexes();
if (auto markerModel = m_model.lock()) {
Fun undo = []() { return true; };
Fun redo = []() { return true; };
QList<int> frames;
for (auto &ix : selection) {
int frame = m_proxy->data(ix, MarkerListModel::FrameRole).toInt();
frames << m_proxy->data(ix, MarkerListModel::FrameRole).toInt();
}
for (auto &frame : frames) {
GenTime pos(frame, pCore->getCurrentFps());
markerModel->removeMarker(pos, undo, redo);
}
......
......@@ -29,13 +29,16 @@ public:
void setModel(std::weak_ptr<MarkerListModel> model, std::shared_ptr<MarkerSortModel> viewModel);
void setClipMarkerModel(std::shared_ptr<ProjectClip> clip);
public slots:
void removeGuide();
void selectAll();
private slots:
void saveGuides();
void editGuides();
void importGuides();
void editGuide(const QModelIndex &ix);
void selectionChanged(const QItemSelection &selected, const QItemSelection &);
void removeGuide();
void addGuide();
void configureGuides();
void rebuildCategories();
......
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