File indexing completed on 2024-04-21 16:31:51
0001 /** 0002 * SPDX-FileCopyrightText: (C) 2003 by Sébastien Laoût <slaout@linux62.org> 0003 * SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "filter.h" 0007 0008 #include <QDialog> 0009 #include <QHBoxLayout> 0010 #include <QLabel> 0011 #include <QLineEdit> 0012 #include <QLocale> 0013 #include <QToolButton> 0014 #include <QtGui/QPixmap> 0015 0016 #include <KComboBox> 0017 #include <KIconLoader> 0018 #include <KLocalizedString> 0019 0020 #include "bnpview.h" 0021 #include "focusedwidgets.h" 0022 #include "global.h" 0023 #include "tag.h" 0024 #include "tools.h" 0025 0026 /** FilterBar */ 0027 0028 FilterBar::FilterBar(QWidget *parent) 0029 : QWidget(parent) /*, m_blinkTimer(this), m_blinkedTimes(0)*/ 0030 { 0031 QHBoxLayout *hBox = new QHBoxLayout(this); 0032 0033 // Create every widgets: 0034 // (Aaron Seigo says we don't need to worry about the 0035 // "Toolbar group" stuff anymore.) 0036 0037 QIcon resetIcon = QIcon::fromTheme("dialog-close"); 0038 QIcon inAllIcon = QIcon::fromTheme("edit-find"); 0039 0040 m_resetButton = new QToolButton(this); 0041 m_resetButton->setIcon(resetIcon); 0042 m_resetButton->setText(i18n("Reset Filter")); //, /*groupText=*/QString(), this, SLOT(reset()), 0); 0043 m_resetButton->setAutoRaise(true); 0044 // new KToolBarButton("locationbar_erase", /*id=*/1230, this, /*name=*/0, i18n("Reset Filter")); 0045 m_lineEdit = new QLineEdit(this); 0046 QLabel *label = new QLabel(this); 0047 label->setText(i18n("&Filter: ")); 0048 label->setBuddy(m_lineEdit); 0049 m_tagsBox = new KComboBox(this); 0050 QLabel *label2 = new QLabel(this); 0051 label2->setText(i18n("T&ag: ")); 0052 label2->setBuddy(m_tagsBox); 0053 m_inAllBasketsButton = new QToolButton(this); 0054 m_inAllBasketsButton->setIcon(inAllIcon); 0055 m_inAllBasketsButton->setText(i18n("Filter All Baskets")); //, /*groupText=*/QString(), this, SLOT(inAllBaskets()), 0); 0056 m_inAllBasketsButton->setAutoRaise(true); 0057 0058 // Configure the Tags combobox: 0059 repopulateTagsCombo(); 0060 0061 // Configure the Search in all Baskets button: 0062 m_inAllBasketsButton->setCheckable(true); 0063 // m_inAllBasketsButton->setChecked(true); 0064 // Global::bnpView->toggleFilterAllBaskets(true); 0065 0066 // m_lineEdit->setMaximumWidth(150); 0067 m_lineEdit->setClearButtonEnabled(true); 0068 0069 // Layout all those widgets: 0070 hBox->addWidget(m_resetButton); 0071 hBox->addWidget(label); 0072 hBox->addWidget(m_lineEdit); 0073 hBox->addWidget(label2); 0074 hBox->addWidget(m_tagsBox); 0075 hBox->addWidget(m_inAllBasketsButton); 0076 0077 //connect(&m_blinkTimer, SIGNAL(timeout()), this, SLOT(blinkBar())); 0078 connect(m_resetButton, &QToolButton::clicked, this, &FilterBar::reset); 0079 connect(m_lineEdit, &QLineEdit::textChanged, this, &FilterBar::changeFilter); 0080 connect(m_tagsBox, SIGNAL(activated(int)), this, SLOT(tagChanged(int))); 0081 0082 //connect(m_inAllBasketsButton, SIGNAL(clicked()), this, SLOT(inAllBaskets())); 0083 m_inAllBasketsButton->setDefaultAction(Global::bnpView->m_actFilterAllBaskets); 0084 0085 FocusWidgetFilter *lineEditF = new FocusWidgetFilter(m_lineEdit); 0086 m_tagsBox->installEventFilter(lineEditF); 0087 connect(lineEditF, &FocusWidgetFilter::escapePressed, this, &FilterBar::reset); 0088 connect(lineEditF, &FocusWidgetFilter::returnPressed, this, &FilterBar::changeFilter); 0089 } 0090 0091 FilterBar::~FilterBar() 0092 { 0093 } 0094 0095 void FilterBar::setFilterData(const FilterData &data) 0096 { 0097 m_lineEdit->setText(data.string); 0098 0099 int index = 0; 0100 switch (data.tagFilterType) { 0101 default: 0102 case FilterData::DontCareTagsFilter: 0103 index = 0; 0104 break; 0105 case FilterData::NotTaggedFilter: 0106 index = 1; 0107 break; 0108 case FilterData::TaggedFilter: 0109 index = 2; 0110 break; 0111 case FilterData::TagFilter: 0112 filterTag(data.tag); 0113 return; 0114 case FilterData::StateFilter: 0115 filterState(data.state); 0116 return; 0117 } 0118 0119 if (m_tagsBox->currentIndex() != index) { 0120 m_tagsBox->setCurrentIndex(index); 0121 tagChanged(index); 0122 } 0123 } 0124 0125 void FilterBar::repopulateTagsCombo() 0126 { 0127 static const int ICON_SIZE = 16; 0128 0129 m_tagsBox->clear(); 0130 m_tagsMap.clear(); 0131 m_statesMap.clear(); 0132 0133 m_tagsBox->addItem(QString()); 0134 m_tagsBox->addItem(i18n("(Not tagged)")); 0135 m_tagsBox->addItem(i18n("(Tagged)")); 0136 0137 int index = 3; 0138 Tag *tag; 0139 State *state; 0140 QString icon; 0141 QString text; 0142 QPixmap emblem; 0143 for (Tag::List::iterator it = Tag::all.begin(); it != Tag::all.end(); ++it) { 0144 tag = *it; 0145 state = tag->states().first(); 0146 // Insert the tag in the combo-box: 0147 if (tag->countStates() > 1) { 0148 text = tag->name(); 0149 icon = QString(); 0150 } else { 0151 text = state->name(); 0152 icon = state->emblem(); 0153 } 0154 emblem = KIconLoader::global()->loadIcon(icon, KIconLoader::Desktop, ICON_SIZE, KIconLoader::DefaultState, QStringList(), nullptr, /*canReturnNull=*/true); 0155 m_tagsBox->insertItem(index, emblem, text); 0156 // Update the mapping: 0157 m_tagsMap.insert(index, tag); 0158 ++index; 0159 // Insert sub-states, if needed: 0160 if (tag->countStates() > 1) { 0161 for (State::List::iterator it2 = tag->states().begin(); it2 != tag->states().end(); ++it2) { 0162 state = *it2; 0163 // Insert the state: 0164 text = state->name(); 0165 icon = state->emblem(); 0166 emblem = KIconLoader::global()->loadIcon(icon, 0167 KIconLoader::Desktop, 0168 ICON_SIZE, 0169 KIconLoader::DefaultState, 0170 QStringList(), 0171 nullptr, 0172 /*canReturnNull=*/true); 0173 // Indent the emblem to show the hierarchy relation: 0174 if (!emblem.isNull()) 0175 emblem = Tools::indentPixmap(emblem, /*depth=*/1, /*deltaX=*/2 * ICON_SIZE / 3); 0176 m_tagsBox->insertItem(index, emblem, text); 0177 // Update the mapping: 0178 m_statesMap.insert(index, state); 0179 ++index; 0180 } 0181 } 0182 } 0183 } 0184 0185 void FilterBar::reset() 0186 { 0187 m_lineEdit->setText(QString()); // m_data->isFiltering will be set to false; 0188 m_lineEdit->clearFocus(); 0189 changeFilter(); 0190 if (m_tagsBox->currentIndex() != 0) { 0191 m_tagsBox->setCurrentIndex(0); 0192 tagChanged(0); 0193 } 0194 hide(); 0195 Q_EMIT newFilter(m_data); 0196 } 0197 0198 void FilterBar::filterTag(Tag *tag) 0199 { 0200 int index = 0; 0201 0202 for (QMap<int, Tag *>::Iterator it = m_tagsMap.begin(); it != m_tagsMap.end(); ++it) 0203 if (it.value() == tag) { 0204 index = it.key(); 0205 break; 0206 } 0207 if (index <= 0) 0208 return; 0209 0210 if (m_tagsBox->currentIndex() != index) { 0211 m_tagsBox->setCurrentIndex(index); 0212 tagChanged(index); 0213 } 0214 } 0215 0216 void FilterBar::filterState(State *state) 0217 { 0218 int index = 0; 0219 0220 for (QMap<int, State *>::Iterator it = m_statesMap.begin(); it != m_statesMap.end(); ++it) 0221 if (it.value() == state) { 0222 index = it.key(); 0223 break; 0224 } 0225 if (index <= 0) 0226 return; 0227 0228 if (m_tagsBox->currentIndex() != index) { 0229 m_tagsBox->setCurrentIndex(index); 0230 tagChanged(index); 0231 } 0232 } 0233 0234 void FilterBar::inAllBaskets() 0235 { 0236 // TODO! 0237 } 0238 0239 void FilterBar::setEditFocus() 0240 { 0241 m_lineEdit->setFocus(); 0242 } 0243 0244 bool FilterBar::hasEditFocus() 0245 { 0246 return m_lineEdit->hasFocus() || m_tagsBox->hasFocus(); 0247 } 0248 0249 const FilterData &FilterBar::filterData() 0250 { 0251 return m_data; 0252 } 0253 0254 void FilterBar::changeFilter() 0255 { 0256 m_data.string = m_lineEdit->text(); 0257 m_data.isFiltering = (!m_data.string.isEmpty() || m_data.tagFilterType != FilterData::DontCareTagsFilter); 0258 if (hasEditFocus()) 0259 m_data.isFiltering = true; 0260 Q_EMIT newFilter(m_data); 0261 } 0262 0263 void FilterBar::tagChanged(int index) 0264 { 0265 m_data.tag = nullptr; 0266 m_data.state = nullptr; 0267 switch (index) { 0268 case 0: 0269 m_data.tagFilterType = FilterData::DontCareTagsFilter; 0270 break; 0271 case 1: 0272 m_data.tagFilterType = FilterData::NotTaggedFilter; 0273 break; 0274 case 2: 0275 m_data.tagFilterType = FilterData::TaggedFilter; 0276 break; 0277 default: 0278 // Try to find if we are filtering a tag: 0279 QMap<int, Tag *>::iterator it = m_tagsMap.find(index); 0280 if (it != m_tagsMap.end()) { 0281 m_data.tagFilterType = FilterData::TagFilter; 0282 m_data.tag = *it; 0283 } else { 0284 // If not, try to find if we are filtering a state: 0285 QMap<int, State *>::iterator it2 = m_statesMap.find(index); 0286 if (it2 != m_statesMap.end()) { 0287 m_data.tagFilterType = FilterData::StateFilter; 0288 m_data.state = *it2; 0289 } else { 0290 // If not (should never happens), do as if the tags filter was reset: 0291 m_data.tagFilterType = FilterData::DontCareTagsFilter; 0292 } 0293 } 0294 break; 0295 } 0296 m_data.isFiltering = (!m_data.string.isEmpty() || m_data.tagFilterType != FilterData::DontCareTagsFilter); 0297 if (hasEditFocus()) 0298 m_data.isFiltering = true; 0299 Q_EMIT newFilter(m_data); 0300 } 0301 0302 #include "moc_filter.cpp"