Warning, file /office/skrooge/skgbasegui/skgshow.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /*************************************************************************** 0002 * SPDX-FileCopyrightText: 2022 S. MANKOWSKI stephane@mankowski.fr 0003 * SPDX-FileCopyrightText: 2022 G. DE BURE support@mankowski.fr 0004 * SPDX-License-Identifier: GPL-3.0-or-later 0005 ***************************************************************************/ 0006 /** @file 0007 * A widget to select what to show. 0008 * 0009 * @author Stephane MANKOWSKI / Guillaume DE BURE 0010 */ 0011 #include "skgshow.h" 0012 0013 #include <klocalizedstring.h> 0014 #include <qdom.h> 0015 #include <qicon.h> 0016 #include <qwidgetaction.h> 0017 0018 #include "skgperiodedit.h" 0019 #include "skgservices.h" 0020 0021 SKGShow::SKGShow(QWidget* iParent) 0022 : QToolButton(iParent), m_mode(OR), m_inTrigger(false), m_displayTitle(true) 0023 { 0024 setPopupMode(QToolButton::InstantPopup); 0025 setToolButtonStyle(Qt::ToolButtonTextBesideIcon); 0026 setAutoRaise(true); 0027 0028 m_menu = new SKGMenu(this); 0029 setMenu(m_menu); 0030 0031 // Time to emit stateChanged 0032 m_timer.setSingleShot(true); 0033 connect(&m_timer, &QTimer::timeout, this, &SKGShow::stateChanged, Qt::QueuedConnection); 0034 0035 hide(); 0036 } 0037 0038 SKGShow::~SKGShow() 0039 { 0040 m_menu = nullptr; 0041 } 0042 0043 SKGShow::OperatorMode SKGShow::getMode() 0044 { 0045 return m_mode; 0046 } 0047 0048 void SKGShow::setMode(SKGShow::OperatorMode iMode) 0049 { 0050 if (m_mode != iMode) { 0051 m_mode = iMode; 0052 Q_EMIT modified(); 0053 } 0054 } 0055 0056 QString SKGShow::getState() 0057 { 0058 QStringList itemsChecked; 0059 if (m_menu != nullptr) { 0060 QList<QAction*> actionsList = m_menu->actions(); 0061 int nb = actionsList.count(); 0062 itemsChecked.reserve(nb); 0063 for (int i = 0; i < nb; ++i) { 0064 QAction* act = actionsList.at(i); 0065 if (act != nullptr) { 0066 auto* wact = qobject_cast<QWidgetAction*>(act); 0067 if (wact != nullptr) { 0068 auto* pedit = qobject_cast<SKGPeriodEdit*>(wact->defaultWidget()); 0069 itemsChecked.push_back(act->data().toString() % ":" % pedit->getState()); 0070 } else { 0071 if (act->isChecked()) { 0072 itemsChecked.push_back(act->data().toString()); 0073 } 0074 } 0075 } 0076 } 0077 } 0078 return SKGServices::stringsToCsv(itemsChecked); 0079 } 0080 0081 void SKGShow::setDefaultState(const QString& iState) 0082 { 0083 m_defaultState = iState; 0084 setState(m_defaultState); 0085 } 0086 0087 void SKGShow::setState(const QString& iState) 0088 { 0089 if (m_menu != nullptr) { 0090 QStringList itemsChecked = SKGServices::splitCSVLine(iState.isEmpty() ? m_defaultState : iState); 0091 0092 int nb = m_actions.count(); 0093 for (int i = 0; i < nb; ++i) { 0094 QAction* act = m_actions.at(i); 0095 if (act != nullptr) { 0096 QString identifier = m_actions.at(i)->data().toString(); 0097 auto* wact = qobject_cast<QWidgetAction*>(act); 0098 if (wact != nullptr) { 0099 auto* pedit = qobject_cast<SKGPeriodEdit*>(wact->defaultWidget()); 0100 for (const auto& item : qAsConst(itemsChecked)) { 0101 if (item.startsWith(identifier % ":")) { 0102 pedit->setState(item.right(item.length() - identifier.length() - 1)); 0103 break; 0104 } 0105 } 0106 } else { 0107 act->setChecked(itemsChecked.contains(identifier)); 0108 } 0109 } 0110 } 0111 0112 // Change tooltip 0113 setToolTip(getTitle()); 0114 0115 // Emit event 0116 emit stateChanged(); 0117 } 0118 } 0119 0120 QString SKGShow::getWhereClause() const 0121 { 0122 QString wc; 0123 if (m_menu != nullptr) { 0124 QList<QAction*> actionsList = m_menu->actions(); 0125 int nb = actionsList.count(); 0126 bool noCheck = true; 0127 for (int i = 0; i < nb; ++i) { 0128 QAction* act = actionsList.at(i); 0129 0130 if (act != nullptr) { 0131 auto* wact = qobject_cast<QWidgetAction*>(act); 0132 if (wact != nullptr) { 0133 auto* pedit = qobject_cast<SKGPeriodEdit*>(wact->defaultWidget()); 0134 if (!wc.isEmpty()) { 0135 wc += (m_mode == OR ? QStringLiteral(" OR ") : QStringLiteral(" AND ")); 0136 } 0137 wc += '(' % pedit->getWhereClause() % ')'; 0138 noCheck = false; 0139 0140 } else { 0141 if (act->isChecked()) { 0142 if (!wc.isEmpty()) { 0143 wc += (m_mode == OR ? QStringLiteral(" OR ") : QStringLiteral(" AND ")); 0144 } 0145 wc += '(' % m_whereclause.value(act) % ')'; 0146 noCheck = false; 0147 0148 if (m_whereclause.value(act).isEmpty()) { 0149 wc = QLatin1String(""); 0150 break; 0151 } 0152 } 0153 } 0154 } 0155 } 0156 if ((nb != 0) && noCheck) { 0157 wc = QStringLiteral("1=0"); 0158 } 0159 } 0160 return wc; 0161 } 0162 0163 QString SKGShow::getTitle() const 0164 { 0165 QString wc; 0166 if (m_menu != nullptr) { 0167 int nb = m_actions.count(); 0168 for (int i = 0; i < nb; ++i) { 0169 QAction* act = m_actions.at(i); 0170 if (act != nullptr) { 0171 auto* wact = qobject_cast<QWidgetAction*>(act); 0172 if (wact != nullptr) { 0173 auto* pedit = qobject_cast<SKGPeriodEdit*>(wact->defaultWidget()); 0174 if (!wc.isEmpty()) { 0175 wc += (m_mode == OR ? QStringLiteral(" + ") : QStringLiteral(" , ")); 0176 } 0177 wc += pedit->text(); 0178 } else { 0179 if (act->isChecked()) { 0180 if (!wc.isEmpty()) { 0181 wc += (m_mode == OR ? QStringLiteral(" + ") : QStringLiteral(" , ")); 0182 } 0183 wc += act->toolTip(); 0184 } 0185 } 0186 } 0187 } 0188 } 0189 return wc; 0190 } 0191 0192 void SKGShow::clear() 0193 { 0194 m_check_to_check.clear(); 0195 m_uncheck_to_check.clear(); 0196 m_check_to_uncheck.clear(); 0197 m_uncheck_to_uncheck.clear(); 0198 m_actions.clear(); 0199 m_icons.clear(); 0200 m_whereclause.clear(); 0201 m_defaultState.clear(); 0202 m_menu->clear(); 0203 } 0204 0205 int SKGShow::count() 0206 { 0207 return m_check_to_check.count(); 0208 } 0209 0210 int SKGShow::addGroupedItem(const QString& iIdentifier, const QString& iText, const QString& iIcon, 0211 const QString& iWhereClose, const QString& iGroup, const QKeySequence& iShortcut) 0212 { 0213 if (m_menu != nullptr) { 0214 QActionGroup* groupAction = m_groups.value(iGroup); 0215 if (groupAction == nullptr) { 0216 groupAction = new QActionGroup(this); 0217 m_groups[iGroup] = groupAction; 0218 } 0219 0220 QString name = iText; 0221 name = name.replace('&', QStringLiteral("&&")); 0222 QAction* act = m_menu->addAction(name); 0223 if (act != nullptr) { 0224 act->setToolTip(name); 0225 act->setIcon(SKGServices::fromTheme(iIcon)); 0226 act->setData(iIdentifier); 0227 act->setCheckable(true); 0228 if (!iShortcut.isEmpty()) { 0229 act->setShortcuts(QList<QKeySequence>() << iShortcut << QKeySequence::fromString("Ctrl+Alt+" % iShortcut.toString())); 0230 } 0231 0232 m_check_to_check[act] = QLatin1String(""); 0233 m_check_to_uncheck[act] = QLatin1String(""); 0234 m_uncheck_to_check[act] = QLatin1String(""); 0235 m_uncheck_to_uncheck[act] = QLatin1String(""); 0236 m_actions.push_back(act); 0237 m_icons.push_back(iIcon); 0238 0239 m_whereclause[act] = iWhereClose; 0240 0241 connect(act, &QAction::toggled, this, &SKGShow::trigger); 0242 0243 groupAction->addAction(act); 0244 } 0245 0246 show(); 0247 0248 return (m_actions.count() - 1); 0249 } 0250 return -1; 0251 } 0252 0253 int SKGShow::addPeriodItem(const QString& iIdentifier) 0254 { 0255 if (m_menu != nullptr) { 0256 auto m_periodEdit1 = new SKGPeriodEdit(this); 0257 0258 // Set default 0259 QDomDocument doc(QStringLiteral("SKGML")); 0260 QDomElement root = doc.createElement(QStringLiteral("parameters")); 0261 doc.appendChild(root); 0262 root.setAttribute(QStringLiteral("period"), SKGServices::intToString(static_cast<int>(SKGPeriodEdit::ALL))); 0263 m_periodEdit1->setState(doc.toString()); 0264 0265 // Add widget in menu 0266 auto act = new QWidgetAction(this); 0267 if (act != nullptr) { 0268 act->setData(iIdentifier); 0269 act->setDefaultWidget(m_periodEdit1); 0270 0271 m_check_to_check[act] = QLatin1String(""); 0272 m_check_to_uncheck[act] = QLatin1String(""); 0273 m_uncheck_to_check[act] = QLatin1String(""); 0274 m_uncheck_to_uncheck[act] = QLatin1String(""); 0275 m_actions.push_back(act); 0276 m_icons.push_back(QLatin1String("")); 0277 0278 m_whereclause[act] = QLatin1String(""); 0279 0280 connect(m_periodEdit1, &SKGPeriodEdit::changed, this, &SKGShow::triggerRefreshOnly); 0281 0282 m_menu->addAction(act); 0283 } 0284 0285 show(); 0286 0287 return (m_actions.count() - 1); 0288 } 0289 return -1; 0290 } 0291 0292 int SKGShow::addItem(const QString& iIdentifier, const QString& iText, const QString& iIcon, 0293 const QString& iWhereClose, 0294 const QString& iListIdToCheckWhenChecked, 0295 const QString& iListIdToUncheckWhenChecked, 0296 const QString& iListIdToCheckWhenUnchecked, 0297 const QString& iListIdToUncheckWhenUnchecked, 0298 const QKeySequence& iShortcut 0299 ) 0300 { 0301 if (m_menu != nullptr) { 0302 QString name = iText; 0303 name = name.replace('&', QStringLiteral("&&")); 0304 QAction* act = m_menu->addAction(name); 0305 if (act != nullptr) { 0306 act->setToolTip(name); 0307 act->setIcon(SKGServices::fromTheme(iIcon)); 0308 act->setData(iIdentifier); 0309 act->setCheckable(true); 0310 if (!iShortcut.isEmpty()) { 0311 act->setShortcuts(QList<QKeySequence>() << iShortcut << QKeySequence::fromString("Ctrl+Alt+" % iShortcut.toString())); 0312 } 0313 0314 m_check_to_check[act] = iListIdToCheckWhenChecked; 0315 m_check_to_uncheck[act] = iListIdToUncheckWhenChecked; 0316 m_uncheck_to_check[act] = iListIdToCheckWhenUnchecked; 0317 m_uncheck_to_uncheck[act] = iListIdToUncheckWhenUnchecked; 0318 m_actions.push_back(act); 0319 m_icons.push_back(iIcon); 0320 0321 m_whereclause[act] = iWhereClose; 0322 0323 connect(act, &QAction::toggled, this, &SKGShow::trigger); 0324 } 0325 0326 show(); 0327 0328 return (m_actions.count() - 1); 0329 } 0330 return -1; 0331 } 0332 0333 void SKGShow::setListIdToCheckWhenChecked(int iIndex, const QString& iIds) 0334 { 0335 m_check_to_check[m_actions.at(iIndex)] = iIds; 0336 } 0337 0338 void SKGShow::setListIdToCheckWhenUnchecked(int iIndex, const QString& iIds) 0339 { 0340 m_uncheck_to_check[m_actions.at(iIndex)] = iIds; 0341 } 0342 0343 void SKGShow::setListIdToUncheckWhenChecked(int iIndex, const QString& iIds) 0344 { 0345 m_check_to_uncheck[m_actions.at(iIndex)] = iIds; 0346 } 0347 0348 void SKGShow::setListIdToUncheckWhenUnchecked(int iIndex, const QString& iIds) 0349 { 0350 m_uncheck_to_uncheck[m_actions.at(iIndex)] = iIds; 0351 } 0352 0353 void SKGShow::addSeparator() 0354 { 0355 if (m_menu != nullptr) { 0356 m_menu->addSeparator(); 0357 } 0358 } 0359 0360 void SKGShow::trigger() 0361 { 0362 auto* act = qobject_cast<QAction*>(sender()); 0363 if ((act != nullptr) && !m_inTrigger) { 0364 m_inTrigger = true; 0365 0366 // Apply rules 0367 QStringList over; 0368 if (act->isChecked()) { 0369 { 0370 // Check items 0371 QStringList items = SKGServices::splitCSVLine(m_check_to_check.value(act)); 0372 int nb = items.count(); 0373 for (int i = 0; i < nb; ++i) { 0374 QAction* act2 = getAction(items.at(i)); 0375 if ((act2 != nullptr) && act2 != act) { 0376 act2->setChecked(true); 0377 } 0378 } 0379 } 0380 0381 { 0382 // Uncheck items 0383 QStringList items = SKGServices::splitCSVLine(m_check_to_uncheck.value(act)); 0384 int nb = items.count(); 0385 for (int i = 0; i < nb; ++i) { 0386 QAction* act2 = getAction(items.at(i)); 0387 if ((act2 != nullptr) && act2 != act) { 0388 act2->setChecked(false); 0389 } 0390 } 0391 } 0392 } else { 0393 { 0394 // Check items 0395 QStringList items = SKGServices::splitCSVLine(m_uncheck_to_check.value(act)); 0396 int nb = items.count(); 0397 for (int i = 0; i < nb; ++i) { 0398 QAction* act2 = getAction(items.at(i)); 0399 if ((act2 != nullptr) && act2 != act) { 0400 act2->setChecked(true); 0401 } 0402 } 0403 } 0404 0405 { 0406 // Uncheck items 0407 QStringList items = SKGServices::splitCSVLine(m_uncheck_to_uncheck.value(act)); 0408 int nb = items.count(); 0409 for (int i = 0; i < nb; ++i) { 0410 QAction* act2 = getAction(items.at(i)); 0411 if ((act2 != nullptr) && act2 != act) { 0412 act2->setChecked(false); 0413 } 0414 } 0415 } 0416 } 0417 0418 // Change tooltip 0419 setToolTip(getTitle()); 0420 0421 // Change icon 0422 QStringList icons; 0423 QString mainIcon; 0424 if (m_menu != nullptr) { 0425 int nb = m_actions.count(); 0426 icons.reserve(nb); 0427 for (int i = 0; i < nb; ++i) { 0428 QAction* act2 = m_actions.at(i); 0429 if ((act2 != nullptr) && act2->isChecked()) { 0430 if (!m_icons.at(i).isEmpty()) { 0431 if (mainIcon.isEmpty()) { 0432 mainIcon = m_icons.at(i); 0433 } else { 0434 icons.push_back(m_icons.at(i)); 0435 } 0436 } else { 0437 if (mainIcon.isEmpty()) { 0438 mainIcon = QStringLiteral("show-menu"); 0439 } 0440 } 0441 } 0442 } 0443 } 0444 if (mainIcon.isEmpty()) { 0445 mainIcon = QStringLiteral("show-menu"); 0446 } 0447 setIcon(SKGServices::fromTheme(mainIcon, icons)); 0448 0449 triggerRefreshOnly(); 0450 0451 m_inTrigger = false; 0452 } 0453 } 0454 0455 void SKGShow::triggerRefreshOnly() 0456 { 0457 // Emit event 0458 m_timer.start(300); 0459 0460 // Change title 0461 refreshTitle(); 0462 } 0463 0464 0465 bool SKGShow::getDisplayTitle() 0466 { 0467 return m_displayTitle; 0468 } 0469 0470 void SKGShow::setDisplayTitle(bool iDisplay) 0471 { 0472 if (m_displayTitle != iDisplay) { 0473 m_displayTitle = iDisplay; 0474 refreshTitle(); 0475 Q_EMIT modified(); 0476 } 0477 } 0478 0479 void SKGShow::refreshTitle() 0480 { 0481 if (m_displayTitle) { 0482 setText(i18n("Show: %1", getTitle())); 0483 } else { 0484 setText(i18n("Show")); 0485 } 0486 } 0487 0488 QAction* SKGShow::getAction(const QString& iIdentifier) const 0489 { 0490 QAction* output = nullptr; 0491 if (m_menu != nullptr) { 0492 QList<QAction*> actionsList = m_menu->actions(); 0493 int nb = actionsList.count(); 0494 for (int i = 0; (output == nullptr) && i < nb; ++i) { 0495 QAction* act = actionsList.at(i); 0496 if ((act != nullptr) && act->data().toString() == iIdentifier) { 0497 output = act; 0498 } 0499 } 0500 } 0501 return output; 0502 } 0503 0504