Commit 46929e31 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle

Implement tag filter in bin

parent 5b7c85c2
Pipeline #12506 passed with stage
in 13 minutes and 7 seconds
......@@ -221,7 +221,7 @@ QVariant AbstractProjectItem::getData(DataType type) const
int AbstractProjectItem::supportedDataCount() const
{
return 4;
return 6;
}
QString AbstractProjectItem::name() const
......
......@@ -774,7 +774,7 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent)
m_tagsWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
m_layout->addWidget(m_tagsWidget);
m_tagsWidget->setVisible(false);
m_layout->setSpacing(0);
m_layout->setContentsMargins(0, 0, 0, 0);
// Search line
......@@ -783,7 +783,7 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent)
// m_searchLine->setClearButtonEnabled(true);
m_searchLine->setPlaceholderText(i18n("Search..."));
m_searchLine->setFocusPolicy(Qt::ClickFocus);
auto *leventEater = new LineEventEater(this);
m_searchLine->installEventFilter(leventEater);
connect(leventEater, &LineEventEater::clearSearchLine, m_searchLine, &QLineEdit::clear);
......@@ -922,7 +922,7 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent)
settingsMenu->addAction(m_showDate);
settingsMenu->addAction(m_showDesc);
settingsMenu->addAction(disableEffects);
// Show tags panel
m_tagAction = new QAction(QIcon::fromTheme(QStringLiteral("tag")), i18n("Tags Panel"), this);
m_tagAction->setCheckable(true);
......@@ -934,7 +934,27 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent)
m_tagsWidget->setVisible(false);
}
});
// Filter menu
m_filterMenu = new QMenu(i18n("Filter"), this);
auto *filterButton = new QToolButton;
filterButton->setIcon(QIcon::fromTheme(QStringLiteral("view-filter")));
filterButton->setToolTip(i18n("Filter"));
filterButton->setMenu(m_filterMenu);
filterButton->setPopupMode(QToolButton::InstantPopup);
m_toolbar->addWidget(filterButton);
connect(m_filterMenu, &QMenu::triggered, [&] (QAction *ac) {
QString action = ac->data().toString();
if (action.startsWith(QLatin1Char('#'))) {
m_proxyModel->slotSetSearchTag(action);
} else {
m_proxyModel->slotSetSearchTag(QString());
}
});
m_tagAction->setCheckable(true);
m_toolbar->addAction(m_tagAction);
auto *button = new QToolButton;
button->setIcon(QIcon::fromTheme(QStringLiteral("kdenlive-menu")));
button->setToolTip(i18n("Options"));
......@@ -1363,6 +1383,23 @@ void Bin::setDocument(KdenliveDoc *project)
}
connect(m_proxyAction, SIGNAL(toggled(bool)), m_doc, SLOT(slotProxyCurrentItem(bool)));
// rebuild filter menu
m_filterMenu->clear();
QActionGroup *filterGrp = new QActionGroup(this);
QAction *clearFilter = new QAction(QIcon::fromTheme(QStringLiteral("edit-clear")), i18n("Clear"), filterGrp);
clearFilter->setCheckable(true);
m_filterMenu->addAction(clearFilter);
int tagsCount = pCore->getProjectTags().size();
for (int i = 1; i <= tagsCount; i++) {
QAction *tag = pCore->window()->actionCollection()->action(QString("tag_%1").arg(i));
if (tag) {
QAction *tagFilter = new QAction(tag->icon(), tag->text(), filterGrp);
tagFilter->setData(tag->data());
tagFilter->setCheckable(true);
m_filterMenu->addAction(tagFilter);
}
}
// connect(m_itemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), m_itemView
// connect(m_itemModel, SIGNAL(updateCurrentItem()), this, SLOT(autoSelect()));
slotInitView(nullptr);
......@@ -1665,7 +1702,12 @@ void Bin::slotInitView(QAction *action)
view->setColumnHidden(1, true);
view->setColumnHidden(2, true);
}
// Type column
view->setColumnHidden(3, true);
// Tags column
view->setColumnHidden(4, true);
// Duration column
view->setColumnHidden(5, true);
m_showDate->setChecked(!view->isColumnHidden(1));
m_showDesc->setChecked(!view->isColumnHidden(2));
connect(view->header(), &QHeaderView::sectionResized, this, &Bin::slotSaveHeaders);
......
......@@ -429,6 +429,7 @@ private:
QActionGroup *m_sortGroup;
SmallJobLabel *m_infoLabel;
TagWidget *m_tagsWidget;
QMenu *m_filterMenu;
/** @brief The info widget for failed jobs. */
KMessageWidget *m_infoMessage;
QStringList m_errorLog;
......
......@@ -91,6 +91,12 @@ int ProjectItemModel::mapToColumn(int column) const
case 3:
return AbstractProjectItem::ClipType;
break;
case 4:
return AbstractProjectItem::DataTag;
break;
case 5:
return AbstractProjectItem::DataDuration;
break;
default:
return AbstractProjectItem::DataName;
}
......@@ -215,7 +221,7 @@ bool ProjectItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action
QString id;
return requestAddBinSubClip(id, list.at(1).toInt(), list.at(2).toInt(), QString(), list.at(0));
}
if (data->hasFormat(QStringLiteral("kdenlive/tag"))) {
// Dropping effect on a Bin item
QString tag = QString::fromUtf8(data->data(QStringLiteral("kdenlive/tag")));
......@@ -245,6 +251,12 @@ QVariant ProjectItemModel::headerData(int section, Qt::Orientation orientation,
case 3:
columnName = i18n("Type");
break;
case 4:
columnName = i18n("Tag");
break;
case 5:
columnName = i18n("Duration");
break;
default:
columnName = i18n("Unknown");
break;
......
......@@ -47,14 +47,24 @@ bool ProjectSortProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &s
bool ProjectSortProxyModel::filterAcceptsRowItself(int sourceRow, const QModelIndex &sourceParent) const
{
int cols = sourceModel()->columnCount();
for (int i = 0; i < cols; i++) {
for (int i = 0; i < 4; i++) {
QModelIndex index0 = sourceModel()->index(sourceRow, i, sourceParent);
if (!index0.isValid()) {
return false;
}
auto model = sourceModel();
auto data = model->data(index0);
if (data.toString().contains(m_searchString, Qt::CaseInsensitive)) {
bool tagAccepted = false;
auto data = sourceModel()->data(index0);
if (!m_searchTag.isEmpty()) {
// Column 4 contains the item tag data
QModelIndex indexTag = sourceModel()->index(sourceRow, 4, sourceParent);
auto tagData = sourceModel()->data(indexTag);
if (tagData.toString().contains(m_searchTag, Qt::CaseInsensitive)) {
tagAccepted = true;
}
} else {
tagAccepted = true;
}
if (tagAccepted && data.toString().contains(m_searchString, Qt::CaseInsensitive)) {
return true;
}
}
......@@ -125,6 +135,12 @@ void ProjectSortProxyModel::slotSetSearchString(const QString &str)
invalidateFilter();
}
void ProjectSortProxyModel::slotSetSearchTag(const QString &str)
{
m_searchTag = str;
invalidateFilter();
}
void ProjectSortProxyModel::onCurrentRowChanged(const QItemSelection &current, const QItemSelection &previous)
{
Q_UNUSED(previous)
......
......@@ -43,6 +43,8 @@ public:
public slots:
/** @brief Set search string that will filter the view */
void slotSetSearchString(const QString &str);
/** @brief Set search tag that will filter the view */
void slotSetSearchTag(const QString &str);
/** @brief Relay datachanged signal from view's model */
void slotDataChanged(const QModelIndex &ix1, const QModelIndex &ix2, const QVector<int> &roles);
......@@ -62,6 +64,7 @@ protected:
private:
QItemSelectionModel *m_selection;
QString m_searchString;
QString m_searchTag;
QCollator m_collator;
signals:
......
......@@ -38,31 +38,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QFontDatabase>
#include <QDrag>
TagListView::TagListView(QWidget *parent)
: QListWidget(parent)
{
setFrameStyle(QFrame::NoFrame);
setSelectionMode(QAbstractItemView::SingleSelection);
setDragEnabled(true);
setDragDropMode(QAbstractItemView::DragOnly);
//connect(this, &QListWidget::itemActivated, this, &EffectBasket::slotAddEffect);
}
QMimeData *TagListView::mimeData(const QList<QListWidgetItem *> list) const
{
if (list.isEmpty()) {
return new QMimeData;
}
QDomDocument doc;
QListWidgetItem *item = list.at(0);
QString effectId = item->data(Qt::UserRole).toString();
auto *mime = new QMimeData;
mime->setData(QStringLiteral("kdenlive/tag"), effectId.toUtf8());
return mime;
}
DragButton::DragButton(int ix, const QString tag, const QString description, QWidget *parent)
: QToolButton(parent)
, m_tag(tag.toLower())
......@@ -82,6 +57,7 @@ DragButton::DragButton(int ix, const QString tag, const QString description, QWi
setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
setCheckable(true);
QAction *ac = new QAction(i18n("Tag %1", ix), this);
ac->setData(m_tag);
ac->setIcon(QIcon(pix));
ac->setCheckable(true);
setDefaultAction(ac);
......@@ -89,7 +65,6 @@ DragButton::DragButton(int ix, const QString tag, const QString description, QWi
connect(ac, &QAction::triggered, [&, ac] (bool checked) {
emit switchTag(m_tag, checked);
});
}
void DragButton::mousePressEvent(QMouseEvent *event)
......
......@@ -22,20 +22,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef KDENLIVE_TAGWIDGET_H
#define KDENLIVE_TAGWIDGET_H
#include <QListWidget>
#include <QToolButton>
class TagListView : public QListWidget
{
Q_OBJECT
public:
explicit TagListView(QWidget *parent);
protected:
QMimeData *mimeData(const QList<QListWidgetItem *> list) const override;
};
/**
* @class DragButton
......
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