File indexing completed on 2025-04-27 03:58:35
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2011-02-14 0007 * Description : pick label widget 0008 * 0009 * SPDX-FileCopyrightText: 2011-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0010 * 0011 * SPDX-License-Identifier: GPL-2.0-or-later 0012 * 0013 * ============================================================ */ 0014 0015 #include "picklabelwidget.h" 0016 0017 // Qt includes 0018 0019 #include <QPainter> 0020 #include <QIcon> 0021 #include <QLayout> 0022 #include <QLabel> 0023 #include <QButtonGroup> 0024 #include <QWidgetAction> 0025 #include <QFontMetrics> 0026 #include <QFont> 0027 #include <QToolButton> 0028 #include <QApplication> 0029 0030 // KDE includes 0031 0032 #if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU) 0033 # pragma GCC diagnostic push 0034 # pragma GCC diagnostic ignored "-Wdeprecated-declarations" 0035 #endif 0036 0037 #if defined(Q_CC_CLANG) 0038 # pragma clang diagnostic push 0039 # pragma clang diagnostic ignored "-Wdeprecated-declarations" 0040 #endif 0041 0042 #include <klocalizedstring.h> 0043 #include <kactioncollection.h> 0044 0045 // Restore warnings 0046 #if !defined(Q_OS_DARWIN) && defined(Q_CC_GNU) 0047 # pragma GCC diagnostic pop 0048 #endif 0049 0050 #if defined(Q_CC_CLANG) 0051 # pragma clang diagnostic pop 0052 #endif 0053 0054 // Local includes 0055 0056 #include "dxmlguiwindow.h" 0057 #include "dexpanderbox.h" 0058 0059 namespace Digikam 0060 { 0061 0062 class Q_DECL_HIDDEN PickLabelWidget::Private 0063 { 0064 0065 public: 0066 0067 explicit Private() 0068 : pickBtns (nullptr), 0069 desc (nullptr), 0070 btnNone (nullptr), 0071 btnRej (nullptr), 0072 btnPndg (nullptr), 0073 btnAccpt (nullptr), 0074 descBox (nullptr), 0075 shortcut (nullptr) 0076 { 0077 } 0078 0079 QButtonGroup* pickBtns; 0080 0081 QLabel* desc; 0082 0083 QToolButton* btnNone; 0084 QToolButton* btnRej; 0085 QToolButton* btnPndg; 0086 QToolButton* btnAccpt; 0087 0088 DHBox* descBox; 0089 0090 DAdjustableLabel* shortcut; 0091 }; 0092 0093 PickLabelWidget::PickLabelWidget(QWidget* const parent) 0094 : DVBox(parent), 0095 d (new Private) 0096 { 0097 setAttribute(Qt::WA_DeleteOnClose); 0098 setFocusPolicy(Qt::NoFocus); 0099 0100 DHBox* const hbox = new DHBox(this); 0101 hbox->setContentsMargins(QMargins()); 0102 hbox->setSpacing(0); 0103 0104 d->btnNone = new QToolButton(hbox); 0105 d->btnNone->setCheckable(true); 0106 d->btnNone->setFocusPolicy(Qt::NoFocus); 0107 d->btnNone->setIcon(buildIcon(NoPickLabel)); 0108 d->btnNone->installEventFilter(this); 0109 0110 d->btnRej = new QToolButton(hbox); 0111 d->btnRej->setCheckable(true); 0112 d->btnRej->setFocusPolicy(Qt::NoFocus); 0113 d->btnRej->setIcon(buildIcon(RejectedLabel)); 0114 d->btnRej->installEventFilter(this); 0115 0116 d->btnPndg = new QToolButton(hbox); 0117 d->btnPndg->setCheckable(true); 0118 d->btnPndg->setFocusPolicy(Qt::NoFocus); 0119 d->btnPndg->setIcon(buildIcon(PendingLabel)); 0120 d->btnPndg->installEventFilter(this); 0121 0122 d->btnAccpt = new QToolButton(hbox); 0123 d->btnAccpt->setCheckable(true); 0124 d->btnAccpt->setFocusPolicy(Qt::NoFocus); 0125 d->btnAccpt->setIcon(buildIcon(AcceptedLabel)); 0126 d->btnAccpt->installEventFilter(this); 0127 0128 d->pickBtns = new QButtonGroup(hbox); 0129 d->pickBtns->addButton(d->btnNone, NoPickLabel); 0130 d->pickBtns->addButton(d->btnRej, RejectedLabel); 0131 d->pickBtns->addButton(d->btnPndg, PendingLabel); 0132 d->pickBtns->addButton(d->btnAccpt, AcceptedLabel); 0133 0134 d->descBox = new DHBox(this); 0135 d->descBox->setContentsMargins(QMargins()); 0136 d->descBox->setSpacing(0); 0137 d->desc = new QLabel(d->descBox); 0138 d->shortcut = new DAdjustableLabel(d->descBox); 0139 QFont fnt = d->shortcut->font(); 0140 fnt.setItalic(true); 0141 d->shortcut->setFont(fnt); 0142 d->shortcut->setAlignment(Qt::AlignRight | Qt::AlignVCenter); 0143 d->shortcut->setWordWrap(false); 0144 0145 setSpacing(0); 0146 setContentsMargins(QMargins()); 0147 setPickLabels(QList<PickLabel>() << NoPickLabel); 0148 setDescriptionBoxVisible(true); 0149 setButtonsExclusive(true); 0150 0151 // ------------------------------------------------------------- 0152 0153 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) 0154 0155 connect(d->pickBtns, SIGNAL(idReleased(int)), 0156 this, SIGNAL(signalPickLabelChanged(int))); 0157 0158 #else 0159 0160 connect(d->pickBtns, SIGNAL(buttonReleased(int)), 0161 this, SIGNAL(signalPickLabelChanged(int))); 0162 0163 #endif 0164 0165 } 0166 0167 PickLabelWidget::~PickLabelWidget() 0168 { 0169 delete d; 0170 } 0171 0172 void PickLabelWidget::setDescriptionBoxVisible(bool b) 0173 { 0174 d->descBox->setVisible(b); 0175 0176 if (!b) 0177 { 0178 Q_FOREACH (QAbstractButton* const btn, d->pickBtns->buttons()) 0179 { 0180 PickLabel id = (PickLabel)(d->pickBtns->id(btn)); 0181 btn->setToolTip(labelPickName(id)); 0182 } 0183 } 0184 } 0185 0186 void PickLabelWidget::setButtonsExclusive(bool b) 0187 { 0188 d->pickBtns->setExclusive(b); 0189 } 0190 0191 void PickLabelWidget::updateDescription(PickLabel label) 0192 { 0193 d->desc->setText(labelPickName(label)); 0194 0195 DXmlGuiWindow* const app = dynamic_cast<DXmlGuiWindow*>(qApp->activeWindow()); 0196 0197 if (app) 0198 { 0199 QAction* const ac = app->actionCollection()->action(QString::fromLatin1("pickshortcut-%1").arg(label)); 0200 0201 if (ac) 0202 { 0203 d->shortcut->setAdjustedText(ac->shortcut().toString()); 0204 } 0205 } 0206 } 0207 0208 bool PickLabelWidget::eventFilter(QObject* obj, QEvent* ev) 0209 { 0210 if (obj == d->btnNone) 0211 { 0212 if (ev->type() == QEvent::Enter) 0213 { 0214 updateDescription(NoPickLabel); 0215 return false; 0216 } 0217 } 0218 0219 if (obj == d->btnRej) 0220 { 0221 if (ev->type() == QEvent::Enter) 0222 { 0223 updateDescription(RejectedLabel); 0224 return false; 0225 } 0226 } 0227 0228 if (obj == d->btnPndg) 0229 { 0230 if (ev->type() == QEvent::Enter) 0231 { 0232 updateDescription(PendingLabel); 0233 return false; 0234 } 0235 } 0236 0237 if (obj == d->btnAccpt) 0238 { 0239 if (ev->type() == QEvent::Enter) 0240 { 0241 updateDescription(AcceptedLabel); 0242 return false; 0243 } 0244 } 0245 0246 // pass the event on to the parent class 0247 0248 return DVBox::eventFilter(obj, ev); 0249 } 0250 0251 void PickLabelWidget::setPickLabels(const QList<PickLabel>& list) 0252 { 0253 Q_FOREACH (QAbstractButton* const btn, d->pickBtns->buttons()) 0254 { 0255 PickLabel id = (PickLabel)(d->pickBtns->id(btn)); 0256 btn->setChecked(list.contains(id)); 0257 updateDescription(id); 0258 } 0259 } 0260 0261 QList<PickLabel> PickLabelWidget::pickLabels() const 0262 { 0263 QList<PickLabel> list; 0264 0265 Q_FOREACH (QAbstractButton* const btn, d->pickBtns->buttons()) 0266 { 0267 if (btn && btn->isChecked()) 0268 list.append((PickLabel)(d->pickBtns->id(btn))); 0269 } 0270 0271 return list; 0272 } 0273 0274 QIcon PickLabelWidget::buildIcon(PickLabel label) 0275 { 0276 switch (label) 0277 { 0278 case RejectedLabel: 0279 { 0280 return QIcon::fromTheme(QLatin1String("flag-red")); 0281 } 0282 0283 case PendingLabel: 0284 { 0285 return QIcon::fromTheme(QLatin1String("flag-yellow")); 0286 } 0287 0288 case AcceptedLabel: 0289 { 0290 return QIcon::fromTheme(QLatin1String("flag-green")); 0291 } 0292 0293 default: 0294 { 0295 break; 0296 } 0297 } 0298 0299 // default : NoPickLabel 0300 0301 return QIcon::fromTheme(QLatin1String("flag-black")); 0302 } 0303 0304 QString PickLabelWidget::labelPickName(PickLabel label) 0305 { 0306 QString name; 0307 0308 switch (label) 0309 { 0310 case RejectedLabel: 0311 { 0312 name = i18nc("@info: pick label name", "Rejected"); 0313 break; 0314 } 0315 0316 case PendingLabel: 0317 { 0318 name = i18nc("@info: pick label name", "Pending"); 0319 break; 0320 } 0321 0322 case AcceptedLabel: 0323 { 0324 name = i18nc("@info: pick label name", "Accepted"); 0325 break; 0326 } 0327 0328 default: // NoPickLabel 0329 { 0330 name = i18nc("@info: pick label name", "None"); 0331 break; 0332 } 0333 } 0334 0335 return name; 0336 } 0337 0338 // ----------------------------------------------------------------------------- 0339 0340 class Q_DECL_HIDDEN PickLabelSelector::Private 0341 { 0342 0343 public: 0344 0345 explicit Private() 0346 : plw(nullptr) 0347 { 0348 } 0349 0350 PickLabelWidget* plw; 0351 }; 0352 0353 PickLabelSelector::PickLabelSelector(QWidget* const parent) 0354 : QPushButton(parent), 0355 d (new Private) 0356 { 0357 QMenu* const popup = new QMenu(this); 0358 setMenu(popup); 0359 0360 QWidgetAction* const action = new QWidgetAction(this); 0361 d->plw = new PickLabelWidget(this); 0362 action->setDefaultWidget(d->plw); 0363 popup->addAction(action); 0364 slotPickLabelChanged(NoPickLabel); 0365 0366 connect(d->plw, SIGNAL(signalPickLabelChanged(int)), 0367 this, SLOT(slotPickLabelChanged(int))); 0368 } 0369 0370 PickLabelSelector::~PickLabelSelector() 0371 { 0372 delete d; 0373 } 0374 0375 PickLabelWidget* PickLabelSelector::pickLabelWidget() const 0376 { 0377 return d->plw; 0378 } 0379 0380 void PickLabelSelector::setPickLabel(PickLabel label) 0381 { 0382 d->plw->setPickLabels(QList<PickLabel>() << label); 0383 slotPickLabelChanged(label); 0384 } 0385 0386 PickLabel PickLabelSelector::pickLabel() 0387 { 0388 QList<PickLabel> list = d->plw->pickLabels(); 0389 0390 if (!list.isEmpty()) 0391 { 0392 return list.first(); 0393 } 0394 0395 return NoPickLabel; 0396 } 0397 0398 void PickLabelSelector::slotPickLabelChanged(int id) 0399 { 0400 setText(QString()); 0401 setIcon(d->plw->buildIcon((PickLabel)id)); 0402 setToolTip(i18nc("@info: pick lablel selector", "Pick Label: %1", d->plw->labelPickName((PickLabel)id))); 0403 menu()->close(); 0404 0405 Q_EMIT signalPickLabelChanged(id); 0406 } 0407 0408 // ----------------------------------------------------------------------------- 0409 0410 PickLabelMenuAction::PickLabelMenuAction(QMenu* const parent) 0411 : QMenu(parent) 0412 { 0413 setTitle(i18nc("@title: pick label menu", "Pick")); 0414 QWidgetAction* const wa = new QWidgetAction(this); 0415 PickLabelWidget* const plw = new PickLabelWidget(parent); 0416 wa->setDefaultWidget(plw); 0417 addAction(wa); 0418 0419 connect(plw, SIGNAL(signalPickLabelChanged(int)), 0420 this, SIGNAL(signalPickLabelChanged(int))); 0421 0422 connect(plw, SIGNAL(signalPickLabelChanged(int)), 0423 parent, SLOT(close())); 0424 } 0425 0426 PickLabelMenuAction::~PickLabelMenuAction() 0427 { 0428 } 0429 0430 } // namespace Digikam 0431 0432 #include "moc_picklabelwidget.cpp"