Commit 6b603b81 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle

Implement tag renaming and save in project file

Related to #287
parent 4c1d2244
Pipeline #12525 passed with stage
in 14 minutes and 7 seconds
......@@ -772,6 +772,7 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent)
// Tags panel
m_tagsWidget = new TagWidget(this);
connect(m_tagsWidget, &TagWidget::switchTag, this, &Bin::switchTag);
connect(m_tagsWidget, &TagWidget::updateProjectTags, this, &Bin::updateTags);
m_tagsWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
m_layout->addWidget(m_tagsWidget);
m_tagsWidget->setVisible(false);
......@@ -949,7 +950,6 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent)
filterButton->setIcon(QIcon::fromTheme(QStringLiteral("view-filter")));
filterButton->setToolTip(i18n("Filter"));
filterButton->setMenu(m_filterMenu);
m_toolbar->addWidget(filterButton);
connect(filterButton, &QToolButton::toggled, [&](bool toggled) {
if (toggled) {
if (m_filterGroup.checkedAction()) {
......@@ -1024,7 +1024,8 @@ Bin::Bin(std::shared_ptr<ProjectItemModel> model, QWidget *parent)
spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_toolbar->addWidget(spacer);
// Add search line
// Add filter and search line
m_toolbar->addWidget(filterButton);
m_toolbar->addWidget(m_searchLine);
m_binTreeViewDelegate = new BinItemDelegate(this);
......@@ -1408,10 +1409,21 @@ void Bin::setDocument(KdenliveDoc *project)
}
connect(m_proxyAction, SIGNAL(toggled(bool)), m_doc, SLOT(slotProxyCurrentItem(bool)));
// rebuild filter menu
// connect(m_itemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), m_itemView
// connect(m_itemModel, SIGNAL(updateCurrentItem()), this, SLOT(autoSelect()));
slotInitView(nullptr);
bool binEffectsDisabled = getDocumentProperty(QStringLiteral("disablebineffects")).toInt() == 1;
setBinEffectsEnabled(!binEffectsDisabled);
QMap <QString, QString> projectTags = m_doc->getProjectTags();
m_tagsWidget->rebuildTags(projectTags);
rebuildFilters(projectTags);
}
void Bin::rebuildFilters(QMap <QString, QString> tags)
{
m_filterMenu->clear();
// Add tag filters
int tagsCount = pCore->getProjectTags().size();
int tagsCount = tags.size();
for (int i = 1; i <= tagsCount; i++) {
QAction *tag = pCore->window()->actionCollection()->action(QString("tag_%1").arg(i));
if (tag) {
......@@ -1459,12 +1471,6 @@ void Bin::setDocument(KdenliveDoc *project)
typeFilter->setData(ClipType::Color);
typeFilter->setCheckable(true);
m_filterMenu->addAction(typeFilter);
// connect(m_itemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), m_itemView
// connect(m_itemModel, SIGNAL(updateCurrentItem()), this, SLOT(autoSelect()));
slotInitView(nullptr);
bool binEffectsDisabled = getDocumentProperty(QStringLiteral("disablebineffects")).toInt() == 1;
setBinEffectsEnabled(!binEffectsDisabled);
}
void Bin::createClip(const QDomElement &xml)
......@@ -2665,6 +2671,12 @@ void Bin::switchTag(const QString &tag, bool add)
editTags(allClips, tag, add);
}
void Bin::updateTags(QMap <QString, QString> tags)
{
rebuildFilters(tags);
pCore->updateProjectTags(tags);
}
void Bin::editTags(QList <QString> allClips, const QString &tag, bool add)
{
for (const QString &id : allClips) {
......
......@@ -324,6 +324,10 @@ private slots:
/** @brief Switch a tag on/off on current selection
*/
void switchTag(const QString &tag, bool add);
/** @brief Update project tags
*/
void updateTags(QMap <QString, QString> tags);
void rebuildFilters(QMap <QString, QString> tags);
/** @brief Switch a tag on a clip list
*/
void editTags(QList <QString> allClips, const QString &tag, bool add);
......
......@@ -36,6 +36,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QToolButton>
#include <QApplication>
#include <QFontDatabase>
#include <QDialog>
#include <QDialogButtonBox>
#include <QListWidget>
#include <QDrag>
DragButton::DragButton(int ix, const QString tag, const QString description, QWidget *parent)
......@@ -56,7 +59,7 @@ DragButton::DragButton(int ix, const QString tag, const QString description, QWi
setText(description);
setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
setCheckable(true);
QAction *ac = new QAction(i18n("Tag %1", ix), this);
QAction *ac = new QAction(description.isEmpty() ? i18n("Tag %1", ix) : description, this);
ac->setData(m_tag);
ac->setIcon(QIcon(pix));
ac->setCheckable(true);
......@@ -110,33 +113,87 @@ const QString &DragButton::tag() const
return m_tag;
}
const QString &DragButton::description() const
{
return m_description;
}
TagWidget::TagWidget(QWidget *parent)
: QWidget(parent)
{
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
QHBoxLayout *lay = new QHBoxLayout;
lay->setContentsMargins(0, 0, 0, 0);
QMap <QString, QString> projectTags = pCore->getProjectTags();
QMapIterator<QString, QString> i(projectTags);
lay->setContentsMargins(2, 0, 2, 0);
lay->addStretch(10);
QToolButton *config = new QToolButton(this);
QAction *ca = new QAction(QIcon::fromTheme(QStringLiteral("configure")), i18n("Configure"), this);
config->setAutoRaise(true);
config->setDefaultAction(ca);
connect(config, &QToolButton::triggered, [&]() {
showTagsConfig ();
});
lay->addWidget(config);
setLayout(lay);
}
void TagWidget::setTagData(const QString tagData)
{
QStringList colors = tagData.toLower().split(QLatin1Char(';'));
for (DragButton *tb : tags) {
const QString color = tb->tag();
tb->defaultAction()->setChecked(colors.contains(color));
}
}
void TagWidget::rebuildTags(QMap <QString, QString> newTags)
{
QHBoxLayout *lay = static_cast<QHBoxLayout *>(layout());
qDeleteAll(tags);
tags.clear();
int ix = 1;
QMapIterator<QString, QString> i(newTags);
while (i.hasNext()) {
i.next();
DragButton *tag1 = new DragButton(ix, i.key(), i.value(), this);
tag1->setFont(font());
connect(tag1, &DragButton::switchTag, this, &TagWidget::switchTag);
tags << tag1;
lay->addWidget(tag1);
lay->insertWidget(ix - 1, tag1);
ix++;
}
lay->addStretch(10);
setLayout(lay);
}
void TagWidget::setTagData(const QString tagData)
void TagWidget::showTagsConfig()
{
QStringList colors = tagData.toLower().split(QLatin1Char(';'));
QDialog d(this);
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel | QDialogButtonBox::Save);
auto *l = new QVBoxLayout;
d.setLayout(l);
QLabel lab(i18n("Configure Project Tags"), &d);
QListWidget list(&d);
l->addWidget(&lab);
l->addWidget(&list);
l->addWidget(buttonBox);
for (DragButton *tb : tags) {
const QString color = tb->tag();
tb->defaultAction()->setChecked(colors.contains(color));
const QString desc = tb->description();
QIcon ic = tb->icon();
QListWidgetItem *item = new QListWidgetItem(ic, desc, &list);
item->setData(Qt::UserRole, color);
item->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
}
d.connect(buttonBox, &QDialogButtonBox::rejected, &d, &QDialog::reject);
d.connect(buttonBox, &QDialogButtonBox::accepted, &d, &QDialog::accept);
if (d.exec() != QDialog::Accepted) {
return;
}
QMap <QString, QString> newTags;
for (int i = 0; i < list.count(); i++) {
QListWidgetItem *item = list.item(i);
if (item) {
newTags.insert(item->data(Qt::UserRole).toString(), item->text());
}
}
rebuildTags(newTags);
emit updateProjectTags(newTags);
}
......@@ -37,6 +37,7 @@ class DragButton : public QToolButton
public:
explicit DragButton(int ix, const QString tag, const QString description = QString(), QWidget *parent = nullptr);
const QString &tag() const;
const QString &description() const;
private:
QPoint m_dragStartPosition;
......@@ -69,12 +70,15 @@ class TagWidget : public QWidget
public:
explicit TagWidget(QWidget *parent = nullptr);
void setTagData(const QString tagData = QString());
void rebuildTags(QMap <QString, QString> newTags);
private:
QList <DragButton *> tags;
void showTagsConfig();
signals:
void switchTag(const QString &tag, bool add);
void updateProjectTags(QMap <QString, QString> newTags);
};
#endif
......@@ -817,13 +817,22 @@ void Core::processInvalidFilter(const QString service, const QString id, const Q
if (m_guiConstructed) m_mainWindow->assetPanelWarning(service, id, message);
}
QMap <QString, QString> Core::getProjectTags()
{
QMap <QString, QString> tags;
tags.insert(QStringLiteral("#ff0000"), i18n("Red"));
tags.insert(QStringLiteral("#00ff00"), i18n("Green"));
tags.insert(QStringLiteral("#0000ff"), i18n("Blue"));
tags.insert(QStringLiteral("#ffff00"), i18n("Yellow"));
tags.insert(QStringLiteral("#00ffff"), i18n("Cyan"));
return tags;
void Core::updateProjectTags(QMap <QString, QString> tags)
{
// Clear previous tags
for (int i = 1 ; i< 20; i++) {
QString current = currentDoc()->getDocumentProperty(QString("tag%1").arg(i));
if (current.isEmpty()) {
break;
} else {
currentDoc()->setDocumentProperty(QString("tag%1").arg(i), QString());
}
}
QMapIterator<QString, QString> j(tags);
int i = 1;
while (j.hasNext()) {
j.next();
currentDoc()->setDocumentProperty(QString("tag%1").arg(i), QString("%1:%2").arg(j.key()).arg(j.value()));
i++;
}
}
......@@ -201,8 +201,8 @@ public:
int getDurationFromString(const QString &time);
/** @brief An error occured within a filter, inform user */
void processInvalidFilter(const QString service, const QString id, const QString message);
/** @brief Returns a list of project tags (color / description) */
QMap <QString, QString> getProjectTags();
/** @brief Update current project's tags */
void updateProjectTags(QMap <QString, QString> tags);
private:
explicit Core();
......
......@@ -1729,3 +1729,24 @@ bool KdenliveDoc::updatePreviewSettings(const QString &profile)
}
return false;
}
QMap <QString, QString> KdenliveDoc::getProjectTags()
{
QMap <QString, QString> tags;
for (int i = 1 ; i< 20; i++) {
QString current = getDocumentProperty(QString("tag%1").arg(i));
if (current.isEmpty()) {
break;
} else {
tags.insert(current.section(QLatin1Char(':'), 0, 0), current.section(QLatin1Char(':'), 1));
}
}
if (tags.isEmpty()) {
tags.insert(QStringLiteral("#ff0000"), i18n("Red"));
tags.insert(QStringLiteral("#00ff00"), i18n("Green"));
tags.insert(QStringLiteral("#0000ff"), i18n("Blue"));
tags.insert(QStringLiteral("#ffff00"), i18n("Yellow"));
tags.insert(QStringLiteral("#00ffff"), i18n("Cyan"));
}
return tags;
}
......@@ -155,6 +155,8 @@ public:
QString getAutoProxyProfile();
/** @brief Returns the number of clips in this project (useful to show loading progress) */
int clipsCount() const;
/** @brief Returns a list of project tags (color / description) */
QMap <QString, QString> getProjectTags();
private:
QUrl m_url;
......
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