File indexing completed on 2024-04-28 08:31:14

0001 /*
0002     SPDX-FileCopyrightText: 2006-2010 Sebastian Trueg <trueg@kde.org>
0003     SPDX-FileCopyrightText: 2011-2013 Vishesh Handa <me@vhanda.in>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "tagwidget.h"
0009 #include "kblocklayout.h"
0010 #include "kedittagsdialog_p.h"
0011 #include "tagcheckbox.h"
0012 
0013 #include <KLocalizedString>
0014 
0015 #include <QLabel>
0016 #include <QMap>
0017 
0018 using namespace Baloo;
0019 
0020 class Baloo::TagWidgetPrivate
0021 {
0022 public:
0023     void init(TagWidget *parent);
0024     void rebuild();
0025     void buildTagHash(const QStringList &tags);
0026 
0027     /// create clickable tag label
0028     void addTagLabel(const QString &tag);
0029 
0030     /// check the corresponding checkboxes and even
0031     /// add missing checkboxes
0032     void selectTags(const QStringList &tags);
0033 
0034     bool m_readOnly = false;
0035 
0036     QMap<QString, TagCheckBox *> m_tagLabels;
0037     QLabel *m_showAllLinkLabel = nullptr;
0038     KBlockLayout *m_flowLayout = nullptr;
0039     TagWidget *q;
0040 
0041     void showEditDialog();
0042     void kEditTagDialogFinished(int result);
0043     KEditTagsDialog *m_editTagsDialog = nullptr;
0044 };
0045 
0046 void TagWidgetPrivate::init(TagWidget *parent)
0047 {
0048     q = parent;
0049 
0050     auto mainLayout = new QGridLayout(q);
0051     mainLayout->setContentsMargins(0, 0, 0, 0);
0052     // TODO spacingHint should be declared. Old code  m_flowLayout = new KBlockLayout( 0, KDialog::spacingHint()*3 );
0053     m_flowLayout = new KBlockLayout(0);
0054     mainLayout->addLayout(m_flowLayout, 0, 0, 1, 2);
0055     mainLayout->setColumnStretch(0, 1);
0056 }
0057 
0058 void TagWidgetPrivate::rebuild()
0059 {
0060     buildTagHash(q->selectedTags());
0061 }
0062 
0063 void TagWidgetPrivate::buildTagHash(const QStringList &tags)
0064 {
0065     qDeleteAll(m_tagLabels);
0066     m_tagLabels.clear();
0067 
0068     for (const QString &tag : tags) {
0069         addTagLabel(tag);
0070     }
0071 
0072     delete m_showAllLinkLabel;
0073     m_showAllLinkLabel = nullptr;
0074 
0075     if (m_readOnly && !tags.isEmpty()) {
0076         return;
0077     }
0078 
0079     m_showAllLinkLabel = new QLabel(q);
0080     m_flowLayout->addWidget(m_showAllLinkLabel);
0081     if (m_readOnly) {
0082         m_showAllLinkLabel->setTextFormat(Qt::PlainText);
0083         m_showAllLinkLabel->setText(QStringLiteral("-"));
0084     } else {
0085         m_showAllLinkLabel->setTextFormat(Qt::RichText);
0086         m_showAllLinkLabel->setText(QStringLiteral("<a href=\"add_tags\">%1</a>").arg(m_tagLabels.isEmpty() ? i18nc("@label", "Add...") : i18nc("@label", "Edit...")));
0087         q->connect(m_showAllLinkLabel, &QLabel::linkActivated, [this]{showEditDialog();});
0088     }
0089 }
0090 
0091 void TagWidgetPrivate::addTagLabel(const QString &tag)
0092 {
0093     const auto it = m_tagLabels.find(tag);
0094     if (it == m_tagLabels.end()) {
0095         auto label = new TagCheckBox(tag, q);
0096         q->connect(label, &TagCheckBox::tagClicked, q, &TagWidget::tagClicked);
0097         m_tagLabels.insert(tag, label);
0098         m_flowLayout->addWidget(label);
0099     }
0100 }
0101 
0102 void TagWidgetPrivate::selectTags(const QStringList &tags)
0103 {
0104     buildTagHash(tags);
0105 }
0106 
0107 TagWidget::TagWidget(QWidget *parent)
0108     : QWidget(parent)
0109     , d(new TagWidgetPrivate())
0110 {
0111     setForegroundRole(parent->foregroundRole());
0112     d->init(this);
0113 }
0114 
0115 TagWidget::~TagWidget() = default;
0116 
0117 QStringList TagWidget::selectedTags() const
0118 {
0119     return d->m_tagLabels.keys();
0120 }
0121 
0122 Qt::Alignment TagWidget::alignment() const
0123 {
0124     return d->m_flowLayout->alignment();
0125 }
0126 
0127 bool TagWidget::readOnly() const
0128 {
0129     return d->m_readOnly;
0130 }
0131 
0132 void TagWidget::setSelectedTags(const QStringList &tags)
0133 {
0134     d->selectTags(tags);
0135 }
0136 
0137 void TagWidget::setAlignment(Qt::Alignment alignment)
0138 {
0139     d->m_flowLayout->setAlignment(alignment);
0140 }
0141 
0142 void TagWidget::setReadyOnly(bool readOnly)
0143 {
0144     d->m_readOnly = readOnly;
0145     d->rebuild();
0146 }
0147 
0148 void TagWidgetPrivate::showEditDialog()
0149 {
0150     m_editTagsDialog = new KEditTagsDialog(m_tagLabels.keys(), q);
0151     m_editTagsDialog->setWindowModality(Qt::ApplicationModal);
0152     q->connect(m_editTagsDialog, &QDialog::finished, q, [this](int result) {kEditTagDialogFinished(result);});
0153     m_editTagsDialog->open();
0154 }
0155 
0156 void TagWidgetPrivate::kEditTagDialogFinished(int result)
0157 {
0158     if (result == QDialog::Accepted) {
0159         selectTags(m_editTagsDialog->tags());
0160         Q_EMIT q->selectionChanged(m_tagLabels.keys());
0161     }
0162 
0163     m_editTagsDialog->deleteLater();
0164     m_editTagsDialog = nullptr;
0165 }
0166 
0167 #include "moc_tagwidget.cpp"