File indexing completed on 2025-03-09 03:57:06

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-05-22
0007  * Description : database key selector.
0008  *
0009  * SPDX-FileCopyrightText: 2010-2012 by Andi Clemens <andi dot clemens at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "dbkeyselector.h"
0016 
0017 // Qt includes
0018 
0019 #include <QHeaderView>
0020 #include <QGridLayout>
0021 #include <QString>
0022 #include <QMap>
0023 #include <QPushButton>
0024 #include <QApplication>
0025 #include <QStyle>
0026 
0027 // KDE includes
0028 
0029 #include <klocalizedstring.h>
0030 
0031 // Local includes
0032 
0033 #include "ditemtooltip.h"
0034 #include "dbkeyscollection.h"
0035 #include "dbheaderlistitem.h"
0036 
0037 namespace Digikam
0038 {
0039 
0040 DbKeySelectorItem::DbKeySelectorItem(DbHeaderListItem* const parent, const QString& title, const QString& desc)
0041     : QTreeWidgetItem(parent),
0042       m_key          (title),
0043       m_description  (desc)
0044 {
0045     setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsUserCheckable);
0046     setCheckState(0, Qt::Unchecked);
0047     setChildIndicatorPolicy(QTreeWidgetItem::DontShowIndicator);
0048 
0049     setText(0, title);
0050 
0051     QString descVal = desc.simplified();
0052 
0053     if (descVal.length() > 512)
0054     {
0055         descVal.truncate(512);
0056         descVal.append(QLatin1String("..."));
0057     }
0058 
0059     setText(1, descVal);
0060 
0061     DToolTipStyleSheet cnt;
0062     setToolTip(1, QLatin1String("<qt><p>") + cnt.breakString(descVal) + QLatin1String("</p></qt>"));
0063 }
0064 
0065 DbKeySelectorItem::~DbKeySelectorItem()
0066 {
0067 }
0068 
0069 QString DbKeySelectorItem::key() const
0070 {
0071     return m_key;
0072 }
0073 
0074 QString DbKeySelectorItem::description() const
0075 {
0076     return m_description;
0077 }
0078 
0079 // ------------------------------------------------------------------------------------
0080 
0081 DbKeySelector::DbKeySelector(QWidget* const parent)
0082     : QTreeWidget(parent)
0083 {
0084     setColumnCount(2);
0085     setRootIsDecorated(false);
0086     setUniformRowHeights(true);
0087     setAllColumnsShowFocus(true);
0088     setSelectionMode(QAbstractItemView::SingleSelection);
0089     setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0090 
0091     QStringList labels;
0092     labels.append(i18n("Key"));
0093     labels.append(i18n("Description"));
0094     setHeaderLabels(labels);
0095     header()->setSectionResizeMode(0, QHeaderView::Stretch);
0096     header()->setSectionResizeMode(1, QHeaderView::Stretch);
0097 }
0098 
0099 DbKeySelector::~DbKeySelector()
0100 {
0101 }
0102 
0103 void DbKeySelector::setKeysMap(const DbOptionKeysMap& map)
0104 {
0105     clear();
0106     setSortingEnabled(true);
0107 
0108     QMap<QString, DbHeaderListItem*> headers;
0109 
0110     for (DbOptionKeysMap::const_iterator it = map.constBegin() ; it != map.constEnd() ; ++it)
0111     {
0112         if (!headers.contains(it.value()->collectionName()))
0113         {
0114             headers.insert(it.value()->collectionName(), new DbHeaderListItem(this, it.value()->collectionName()));
0115         }
0116 
0117         new DbKeySelectorItem(headers.value(it.value()->collectionName()),
0118                               it.key(),
0119                               it.value()->ids().value(it.key()));
0120     }
0121 
0122     sortByColumn(0, Qt::AscendingOrder);
0123     setSortingEnabled(false);
0124 }
0125 
0126 QStringList DbKeySelector::checkedKeysList()
0127 {
0128     QStringList list;
0129     QTreeWidgetItemIterator it(this, QTreeWidgetItemIterator::Checked);
0130 
0131     while (*it)
0132     {
0133         DbKeySelectorItem* const item = dynamic_cast<DbKeySelectorItem*>(*it);
0134 
0135         if (item)
0136         {
0137             list.append(item->key());
0138         }
0139 
0140         ++it;
0141     }
0142 
0143     return list;
0144 }
0145 
0146 // ------------------------------------------------------------------------------------
0147 
0148 class Q_DECL_HIDDEN DbKeySelectorView::Private
0149 {
0150 public:
0151 
0152     explicit Private()
0153       : selector (nullptr),
0154         searchBar(nullptr)
0155     {
0156     }
0157 
0158     DbKeySelector* selector;
0159     SearchTextBar* searchBar;
0160 };
0161 
0162 DbKeySelectorView::DbKeySelectorView(QWidget* const parent)
0163     : QWidget(parent),
0164       d      (new Private)
0165 {
0166     const int spacing       = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0167                              QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0168 
0169     QGridLayout* const grid = new QGridLayout(this);
0170     d->selector             = new DbKeySelector(this);
0171     d->searchBar            = new SearchTextBar(this, QLatin1String("DbKeySelectorView"));
0172 
0173     grid->addWidget(d->selector,  0, 0, 1, 1);
0174     grid->addWidget(d->searchBar, 1, 0, 1, 1);
0175     grid->setColumnStretch(0, 10);
0176     grid->setRowStretch(0, 10);
0177     grid->setContentsMargins(spacing, spacing, spacing, spacing);
0178     grid->setSpacing(spacing);
0179 
0180     connect(d->searchBar, SIGNAL(signalSearchTextSettings(SearchTextSettings)),
0181             this, SLOT(slotSearchTextChanged(SearchTextSettings)));
0182 }
0183 
0184 DbKeySelectorView::~DbKeySelectorView()
0185 {
0186     delete d;
0187 }
0188 
0189 void DbKeySelectorView::setKeysMap(const DbOptionKeysMap& map)
0190 {
0191     d->selector->setKeysMap(map);
0192 }
0193 
0194 QStringList DbKeySelectorView::checkedKeysList() const
0195 {
0196     d->searchBar->clear();
0197 
0198     return d->selector->checkedKeysList();
0199 }
0200 
0201 void DbKeySelectorView::slotSearchTextChanged(const SearchTextSettings& settings)
0202 {
0203     QString search       = settings.text;
0204     bool atleastOneMatch = false;
0205 
0206     // Restore all DbKey items.
0207 
0208     QTreeWidgetItemIterator it2(d->selector);
0209 
0210     while (*it2)
0211     {
0212         DbHeaderListItem* const item = dynamic_cast<DbHeaderListItem*>(*it2);
0213 
0214         if (item)
0215         {
0216             item->setHidden(false);
0217         }
0218 
0219         ++it2;
0220     }
0221 
0222     QTreeWidgetItemIterator it(d->selector);
0223 
0224     while (*it)
0225     {
0226         DbKeySelectorItem* const item = dynamic_cast<DbKeySelectorItem*>(*it);
0227 
0228         if (item)
0229         {
0230             bool match = item->description().contains(search, settings.caseSensitive) ||
0231                          item->key().contains(search, settings.caseSensitive);
0232 
0233             if (match)
0234             {
0235                 atleastOneMatch = true;
0236                 item->setHidden(false);
0237             }
0238             else
0239             {
0240                 item->setHidden(true);
0241             }
0242         }
0243 
0244         ++it;
0245     }
0246 
0247     removeChildlessHeaders();
0248     d->searchBar->slotSearchResult(atleastOneMatch);
0249 }
0250 
0251 void DbKeySelectorView::removeChildlessHeaders()
0252 {
0253     QTreeWidgetItemIterator it(d->selector);
0254 
0255     while (*it)
0256     {
0257         DbHeaderListItem* const item = dynamic_cast<DbHeaderListItem*>(*it);
0258 
0259         if (item)
0260         {
0261             int children   = item->childCount();
0262             int visibles = 0;
0263 
0264             for (int i = 0 ; i < children ; ++i)
0265             {
0266                 QTreeWidgetItem* const citem = (*it)->child(i);
0267 
0268                 if (!citem->isHidden())
0269                 {
0270                     ++visibles;
0271                 }
0272             }
0273 
0274             if (!children || !visibles)
0275             {
0276                 item->setHidden(true);
0277             }
0278         }
0279 
0280         ++it;
0281     }
0282 }
0283 
0284 } // namespace Digikam
0285 
0286 #include "moc_dbkeyselector.cpp"