File indexing completed on 2025-01-05 04:00:03
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-04-18 0007 * Description : User interface for searches 0008 * 0009 * SPDX-FileCopyrightText: 2008-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "choicesearchutilities.h" 0016 0017 // Qt includes 0018 0019 #include <QTreeView> 0020 0021 // Local includes 0022 0023 #include "digikam_debug.h" 0024 #include "searchutilities.h" 0025 0026 namespace Digikam 0027 { 0028 0029 ChoiceSearchModel::Entry::Entry() 0030 : m_checkState(false) 0031 { 0032 } 0033 0034 ChoiceSearchModel::Entry::Entry(const QVariant& key, const QString& userDisplay) 0035 : m_key (key), 0036 m_display (userDisplay), 0037 m_checkState(false) 0038 { 0039 } 0040 0041 bool ChoiceSearchModel::Entry::operator==(const Entry& other) const 0042 { 0043 return (m_key == other.m_key); 0044 } 0045 0046 ChoiceSearchModel::ChoiceSearchModel(QObject* const parent) 0047 : QAbstractListModel(parent) 0048 { 0049 } 0050 0051 void ChoiceSearchModel::setChoice(const QMap<int, QString>& data) 0052 { 0053 if (m_entries.size()) 0054 { 0055 beginResetModel(); 0056 m_entries.clear(); 0057 endResetModel(); 0058 } 0059 0060 for (QMap<int, QString>::const_iterator it = data.constBegin() ; it != data.constEnd() ; ++it) 0061 { 0062 m_entries << Entry(it.key(), it.value()); 0063 } 0064 } 0065 0066 void ChoiceSearchModel::setChoice(const QVariantList& data) 0067 { 0068 if (m_entries.size()) 0069 { 0070 beginResetModel(); 0071 m_entries.clear(); 0072 endResetModel(); 0073 } 0074 0075 Q_ASSERT(data.size() % 2 == 0); 0076 0077 for (QVariantList::const_iterator it = data.constBegin() ; it != data.constEnd() ; ) 0078 { 0079 QVariant key = *it; 0080 ++it; 0081 QString value = (*it).toString(); 0082 ++it; 0083 m_entries << Entry(key, value); 0084 } 0085 } 0086 0087 void ChoiceSearchModel::setChoice(const QStringList& data) 0088 { 0089 if (m_entries.size()) 0090 { 0091 beginResetModel(); 0092 m_entries.clear(); 0093 endResetModel(); 0094 } 0095 0096 Q_ASSERT(data.size() % 2 == 0); 0097 0098 for (QStringList::const_iterator it = data.constBegin() ; it != data.constEnd() ; ) 0099 { 0100 QVariant key = *it; 0101 ++it; 0102 QString value = *it; 0103 ++it; 0104 m_entries << Entry(key, value); 0105 } 0106 } 0107 0108 QVariantList ChoiceSearchModel::checkedKeys() const 0109 { 0110 QVariantList list; 0111 0112 for (QList<Entry>::const_iterator it = m_entries.constBegin() ; it != m_entries.constEnd() ; ++it) 0113 { 0114 if ((*it).m_checkState) 0115 { 0116 list << (*it).m_key; 0117 } 0118 } 0119 0120 return list; 0121 } 0122 0123 QStringList ChoiceSearchModel::checkedDisplayTexts() const 0124 { 0125 QStringList list; 0126 0127 for (QList<Entry>::const_iterator it = m_entries.constBegin() ; it != m_entries.constEnd() ; ++it) 0128 { 0129 if ((*it).m_checkState) 0130 { 0131 list << (*it).m_display; 0132 } 0133 } 0134 0135 return list; 0136 } 0137 0138 void ChoiceSearchModel::setChecked(int i, bool checked) 0139 { 0140 m_entries[i].m_checkState = checked; 0141 QModelIndex modelIndex = index(i); 0142 0143 Q_EMIT dataChanged(modelIndex, modelIndex); 0144 Q_EMIT checkStateChanged(m_entries.at(i).m_key, checked); 0145 } 0146 0147 void ChoiceSearchModel::resetChecked() 0148 { 0149 for (int i = 0 ; i < m_entries.size() ; ++i) 0150 { 0151 if (m_entries.at(i).m_checkState) 0152 { 0153 setChecked(i, false); 0154 } 0155 } 0156 } 0157 0158 int ChoiceSearchModel::rowCount(const QModelIndex& parent) const 0159 { 0160 if (parent.isValid()) 0161 { 0162 return 0; 0163 } 0164 0165 return m_entries.count(); 0166 } 0167 0168 QVariant ChoiceSearchModel::data(const QModelIndex& index, int role) const 0169 { 0170 if (index.isValid()) 0171 { 0172 if (role == Qt::DisplayRole) 0173 { 0174 return m_entries.at(index.row()).m_display; 0175 } 0176 else if (role == Qt::CheckStateRole) 0177 { 0178 return m_entries.at(index.row()).m_checkState ? Qt::Checked : Qt::Unchecked; 0179 } 0180 else if (role == IdRole) 0181 { 0182 return m_entries.at(index.row()).m_key; 0183 } 0184 } 0185 0186 return QVariant(); 0187 } 0188 0189 QModelIndex ChoiceSearchModel::index(int row, int column, const QModelIndex& parent) const 0190 { 0191 if (parent.isValid() || (column != 0) || (row >= m_entries.size())) 0192 { 0193 return QModelIndex(); 0194 } 0195 0196 return createIndex(row, 0); 0197 } 0198 0199 Qt::ItemFlags ChoiceSearchModel::flags(const QModelIndex& index) const 0200 { 0201 return QAbstractListModel::flags(index) | Qt::ItemIsUserCheckable; 0202 } 0203 0204 bool ChoiceSearchModel::setData(const QModelIndex& index, const QVariant& value, int role) 0205 { 0206 if (role == Qt::CheckStateRole) 0207 { 0208 Qt::CheckState state = (Qt::CheckState)value.toInt(); 0209 setChecked(index.row(), state == Qt::Checked); 0210 0211 return true; 0212 } 0213 else 0214 { 0215 return QAbstractListModel::setData(index, value, role); 0216 } 0217 } 0218 0219 // -------------------------------------------------------------------------------------- 0220 0221 ChoiceSearchComboBox::ChoiceSearchComboBox(QWidget* const parent) 0222 : ListViewComboBox(parent), 0223 m_label (nullptr) 0224 { 0225 } 0226 0227 void ChoiceSearchComboBox::setSearchModel(ChoiceSearchModel* model) 0228 { 0229 ModelIndexBasedComboBox::setModel(model); 0230 installView(); 0231 } 0232 0233 ChoiceSearchModel* ChoiceSearchComboBox::model() const 0234 { 0235 return static_cast<ChoiceSearchModel*>(ListViewComboBox::model()); 0236 } 0237 0238 DSqueezedClickLabel* ChoiceSearchComboBox::label() const 0239 { 0240 return m_label; 0241 } 0242 0243 void ChoiceSearchComboBox::setLabelText(const QString& text) 0244 { 0245 m_label->setAdjustedText(text); 0246 } 0247 0248 void ChoiceSearchComboBox::labelClicked() 0249 { 0250 qCDebug(DIGIKAM_GENERAL_LOG) << "labelClicked"; 0251 showPopup(); 0252 } 0253 0254 void ChoiceSearchComboBox::installView(QAbstractItemView* v) 0255 { 0256 // make protected again 0257 0258 ListViewComboBox::installView(v); 0259 /* 0260 view()->setHeaderHidden(true); 0261 */ 0262 view()->setAlternatingRowColors(true); 0263 0264 // create the label 0265 0266 m_label = new DSqueezedClickLabel; 0267 0268 if (layoutDirection() == Qt::RightToLeft) 0269 { 0270 m_label->setElideMode(Qt::ElideRight); 0271 } 0272 else 0273 { 0274 m_label->setElideMode(Qt::ElideLeft); 0275 } 0276 0277 // set a line edit that carries the label 0278 0279 ProxyClickLineEdit* const lineEdit = new ProxyClickLineEdit; 0280 lineEdit->setCursor(m_label->cursor()); 0281 lineEdit->setWidget(m_label); 0282 setLineEdit(lineEdit); 0283 0284 // connect clicks on upper area (both line edit and widget within) to showPopup 0285 0286 connect(lineEdit, SIGNAL(leftClicked()), 0287 this, SLOT(labelClicked())); 0288 0289 connect(m_label, SIGNAL(activated()), 0290 this, SLOT(labelClicked())); 0291 } 0292 0293 } // namespace Digikam 0294 0295 #include "moc_choicesearchutilities.cpp"