File indexing completed on 2024-11-03 04:29:23
0001 /* 0002 * SPDX-FileCopyrightText: 2022 Jean-Baptiste Mardelle <jb.kdenlive@org> 0003 * SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0004 */ 0005 #include "markercategorybutton.h" 0006 #include "../bin/model/markerlistmodel.hpp" 0007 #include "core.h" 0008 0009 #include <KLocalizedString> 0010 #include <QMenu> 0011 0012 MarkerCategoryButton::MarkerCategoryButton(QWidget *parent) 0013 : QToolButton(parent) 0014 , m_markerListModel(nullptr) 0015 , m_allowAll(true) 0016 , m_onlyUsed(false) 0017 { 0018 setCheckable(false); 0019 setIcon(QIcon::fromTheme(QLatin1String("view-filter"))); 0020 setPopupMode(QToolButton::InstantPopup); 0021 m_menu = new QMenu(this); 0022 setMenu(m_menu); 0023 if (pCore) { 0024 refresh(); 0025 } 0026 connect(m_menu, &QMenu::triggered, this, &MarkerCategoryButton::categorySelected); 0027 connect(this, &MarkerCategoryButton::changed, this, &MarkerCategoryButton::refresh); 0028 } 0029 0030 void MarkerCategoryButton::enableFilterMode() 0031 { 0032 setCheckable(true); 0033 setPopupMode(QToolButton::MenuButtonPopup); 0034 } 0035 0036 void MarkerCategoryButton::categorySelected(QAction *ac) 0037 { 0038 int index = ac->data().toInt(); 0039 QList<QAction *> actions = m_menu->actions(); 0040 if (index == -1) { 0041 if (!ac->isChecked()) { 0042 // Don't allow unselecting all categories 0043 ac->setChecked(true); 0044 if (isCheckable()) { 0045 setChecked(false); 0046 } 0047 return; 0048 } 0049 // All categories selected, unselect any other 0050 for (auto &action : actions) { 0051 if (action != ac && action->isChecked()) { 0052 action->setChecked(false); 0053 } 0054 } 0055 Q_EMIT categoriesChanged({-1}); 0056 if (isCheckable()) { 0057 setChecked(false); 0058 } 0059 return; 0060 } else { 0061 // If a category is selected, ensure "all categories" is unchecked 0062 if (!ac->isChecked()) { 0063 bool categorySelected = false; 0064 for (auto &action : actions) { 0065 if (action->data().toInt() != -1 && action->isChecked()) { 0066 categorySelected = true; 0067 break; 0068 } 0069 } 0070 if (!categorySelected) { 0071 for (auto &action : actions) { 0072 if (action->data().toInt() == -1) { 0073 action->setChecked(true); 0074 break; 0075 } 0076 } 0077 } 0078 } else { 0079 // A category is checked, ensure "all categories is unchecked 0080 for (auto &action : actions) { 0081 if (action->data().toInt() == -1) { 0082 action->setChecked(false); 0083 break; 0084 } 0085 } 0086 } 0087 } 0088 QList<int> selection; 0089 for (auto &action : actions) { 0090 if (action->isChecked()) { 0091 selection << action->data().toInt(); 0092 } 0093 } 0094 Q_EMIT categoriesChanged(selection); 0095 if (isCheckable()) { 0096 setChecked(selection != (QList<int>() << -1)); 0097 } 0098 } 0099 0100 void MarkerCategoryButton::refresh() 0101 { 0102 QList<int> selected; 0103 // remember selected categories 0104 QList<QAction *> actions = m_menu->actions(); 0105 for (auto &ac : actions) { 0106 if (ac->isChecked()) { 0107 selected << ac->data().toInt(); 0108 } 0109 } 0110 m_menu->clear(); 0111 // Set up guide categories 0112 QPixmap pixmap(32, 32); 0113 QMapIterator<int, Core::MarkerCategory> i(pCore->markerTypes); 0114 while (i.hasNext()) { 0115 i.next(); 0116 if (m_onlyUsed && m_markerListModel && m_markerListModel->getAllMarkers(i.key()).isEmpty()) { 0117 continue; 0118 } 0119 pixmap.fill(i.value().color); 0120 QIcon colorIcon(pixmap); 0121 QAction *ac = new QAction(colorIcon, i.value().displayName, m_menu); 0122 ac->setData(i.key()); 0123 ac->setCheckable(true); 0124 ac->setChecked(selected.contains(i.key())); 0125 m_menu->addAction(ac); 0126 } 0127 if (m_menu->actions().count() == 0 && !m_allowAll) { 0128 setEnabled(false); 0129 setText(i18n("Nothing to select")); 0130 return; 0131 } 0132 setEnabled(true); 0133 if (m_allowAll) { 0134 QAction *ac = new QAction(i18n("All Categories"), m_menu); 0135 ac->setData(-1); 0136 ac->setCheckable(true); 0137 if (m_menu->actions().isEmpty()) { 0138 m_menu->addAction(ac); 0139 } else { 0140 m_menu->insertAction(m_menu->actions().first(), ac); 0141 } 0142 if (selected.isEmpty() || selected.contains(-1)) { 0143 ac->setChecked(true); 0144 } 0145 } 0146 } 0147 0148 void MarkerCategoryButton::setCurrentCategories(QList<int> categories) 0149 { 0150 QList<QAction *> actions = m_menu->actions(); 0151 if (categories.contains(-1)) { 0152 for (auto &ac : actions) { 0153 if (ac->data().toInt() == -1) { 0154 ac->setChecked(true); 0155 } else { 0156 ac->setChecked(false); 0157 } 0158 } 0159 } else { 0160 for (auto &ac : actions) { 0161 int categoryIndex = ac->data().toInt(); 0162 if (categoryIndex == -1) { 0163 ac->setChecked(false); 0164 } else { 0165 ac->setChecked(categories.contains(categoryIndex)); 0166 } 0167 } 0168 } 0169 } 0170 0171 QList<int> MarkerCategoryButton::currentCategories() 0172 { 0173 QList<int> selected; 0174 QList<QAction *> actions = m_menu->actions(); 0175 for (auto &ac : actions) { 0176 if (ac->isChecked()) { 0177 selected << ac->data().toInt(); 0178 } 0179 } 0180 if (selected.contains(-1)) { 0181 return {-1}; 0182 } 0183 return selected; 0184 } 0185 0186 void MarkerCategoryButton::setMarkerModel(const MarkerListModel *model) 0187 { 0188 m_markerListModel = model; 0189 connect(m_markerListModel, &MarkerListModel::categoriesChanged, this, &MarkerCategoryButton::changed); 0190 Q_EMIT changed(); 0191 } 0192 0193 void MarkerCategoryButton::setAllowAll(bool allowAll) 0194 { 0195 m_allowAll = allowAll; 0196 Q_EMIT changed(); 0197 } 0198 0199 void MarkerCategoryButton::setOnlyUsed(bool onlyUsed) 0200 { 0201 m_onlyUsed = onlyUsed; 0202 if (m_onlyUsed) { 0203 connect(m_menu, &QMenu::aboutToShow, this, &MarkerCategoryButton::changed); 0204 } 0205 Q_EMIT changed(); 0206 }