File indexing completed on 2025-04-27 03:58:30
0001 /* ============================================================ 0002 * 0003 * This file is a part of digiKam project 0004 * https://www.digikam.org 0005 * 0006 * Date : 2008-03-14 0007 * Description : A widget to host settings as expander box 0008 * 0009 * SPDX-FileCopyrightText: 2008-2013 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de> 0010 * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com> 0011 * SPDX-FileCopyrightText: 2010 by Manuel Viet <contact at 13zenrv dot fr> 0012 * SPDX-FileCopyrightText: 2001 by Frerich Raabe <raabe at kde dot org> 0013 * 0014 * SPDX-License-Identifier: GPL-2.0-or-later 0015 * 0016 * ============================================================ */ 0017 0018 #include "dexpanderbox.h" 0019 0020 // Qt includes 0021 0022 #include <QApplication> 0023 #include <QMouseEvent> 0024 #include <QPainter> 0025 #include <QStyle> 0026 #include <QStyleOption> 0027 #include <QToolButton> 0028 #include <QGridLayout> 0029 #include <QHBoxLayout> 0030 #include <QCheckBox> 0031 #include <QScreen> 0032 #include <QWindow> 0033 0034 // KDE includes 0035 0036 #include <kconfiggroup.h> 0037 0038 // Local includes 0039 0040 #include "dlayoutbox.h" 0041 0042 namespace Digikam 0043 { 0044 0045 DLineWidget::DLineWidget(Qt::Orientation orientation, QWidget* const parent) 0046 : QFrame(parent) 0047 { 0048 setLineWidth(1); 0049 setMidLineWidth(0); 0050 setFrameShadow(QFrame::Sunken); 0051 0052 if (orientation == Qt::Vertical) 0053 { 0054 setFrameShape(QFrame::VLine); 0055 setMinimumSize(2, 0); 0056 } 0057 else 0058 { 0059 setFrameShape(QFrame::HLine); 0060 setMinimumSize(0, 2); 0061 } 0062 0063 updateGeometry(); 0064 } 0065 0066 DLineWidget::~DLineWidget() 0067 { 0068 } 0069 0070 // ------------------------------------------------------------------------------------ 0071 0072 class Q_DECL_HIDDEN DAdjustableLabel::Private 0073 { 0074 public: 0075 0076 explicit Private() 0077 : emode(Qt::ElideMiddle) 0078 { 0079 } 0080 0081 QString ajdText; 0082 Qt::TextElideMode emode; 0083 }; 0084 0085 DAdjustableLabel::DAdjustableLabel(QWidget* const parent) 0086 : QLabel(parent), 0087 d (new Private) 0088 { 0089 setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); 0090 } 0091 0092 DAdjustableLabel::~DAdjustableLabel() 0093 { 0094 delete d; 0095 } 0096 0097 void DAdjustableLabel::resizeEvent(QResizeEvent*) 0098 { 0099 adjustTextToLabel(); 0100 } 0101 0102 QSize DAdjustableLabel::minimumSizeHint() const 0103 { 0104 QSize sh = QLabel::minimumSizeHint(); 0105 sh.setWidth(-1); 0106 return sh; 0107 } 0108 0109 QSize DAdjustableLabel::sizeHint() const 0110 { 0111 QScreen* screen = qApp->primaryScreen(); 0112 0113 if (QWidget* const widget = nativeParentWidget()) 0114 { 0115 if (QWindow* const window = widget->windowHandle()) 0116 { 0117 screen = window->screen(); 0118 } 0119 } 0120 0121 QFontMetrics fm(fontMetrics()); 0122 int maxW = screen->geometry().width() * 3 / 4; 0123 int currentW = fm.horizontalAdvance(d->ajdText); 0124 0125 return (QSize(currentW > maxW ? maxW : currentW, QLabel::sizeHint().height())); 0126 } 0127 0128 void DAdjustableLabel::setAdjustedText(const QString& text) 0129 { 0130 d->ajdText = text; 0131 0132 if (d->ajdText.isNull()) 0133 { 0134 QLabel::clear(); 0135 } 0136 0137 adjustTextToLabel(); 0138 } 0139 0140 QString DAdjustableLabel::adjustedText() const 0141 { 0142 return d->ajdText; 0143 } 0144 0145 void DAdjustableLabel::setAlignment(Qt::Alignment alignment) 0146 { 0147 QString tmp(d->ajdText); 0148 QLabel::setAlignment(alignment); 0149 d->ajdText = tmp; 0150 } 0151 0152 void DAdjustableLabel::setElideMode(Qt::TextElideMode mode) 0153 { 0154 d->emode = mode; 0155 adjustTextToLabel(); 0156 } 0157 0158 void DAdjustableLabel::adjustTextToLabel() 0159 { 0160 QFontMetrics fm(fontMetrics()); 0161 QStringList adjustedLines; 0162 int lblW = size().width(); 0163 bool adjusted = false; 0164 0165 Q_FOREACH (const QString& line, d->ajdText.split(QLatin1Char('\n'))) 0166 { 0167 int lineW = fm.horizontalAdvance(line); 0168 0169 if (lineW > lblW) 0170 { 0171 adjusted = true; 0172 adjustedLines << fm.elidedText(line, d->emode, lblW); 0173 } 0174 else 0175 { 0176 adjustedLines << line; 0177 } 0178 } 0179 0180 if (adjusted) 0181 { 0182 QLabel::setText(adjustedLines.join(QLatin1Char('\n'))); 0183 setToolTip(d->ajdText); 0184 } 0185 else 0186 { 0187 QLabel::setText(d->ajdText); 0188 setToolTip(QString()); 0189 } 0190 } 0191 0192 // ------------------------------------------------------------------------------------ 0193 0194 DClickLabel::DClickLabel(QWidget* const parent) 0195 : QLabel(parent) 0196 { 0197 setCursor(Qt::PointingHandCursor); 0198 } 0199 0200 DClickLabel::DClickLabel(const QString& text, QWidget* const parent) 0201 : QLabel(text, parent) 0202 { 0203 setCursor(Qt::PointingHandCursor); 0204 } 0205 0206 DClickLabel::~DClickLabel() 0207 { 0208 } 0209 0210 void DClickLabel::mousePressEvent(QMouseEvent* event) 0211 { 0212 QLabel::mousePressEvent(event); 0213 0214 /* 0215 * In some contexts, like QGraphicsView, there will be no 0216 * release event if the press event was not accepted. 0217 */ 0218 if (event->button() == Qt::LeftButton) 0219 { 0220 event->accept(); 0221 } 0222 } 0223 0224 void DClickLabel::mouseReleaseEvent(QMouseEvent* event) 0225 { 0226 QLabel::mouseReleaseEvent(event); 0227 0228 if (event->button() == Qt::LeftButton) 0229 { 0230 Q_EMIT leftClicked(); 0231 Q_EMIT activated(); 0232 event->accept(); 0233 } 0234 } 0235 0236 void DClickLabel::keyPressEvent(QKeyEvent* e) 0237 { 0238 switch (e->key()) 0239 { 0240 case Qt::Key_Down: 0241 case Qt::Key_Right: 0242 case Qt::Key_Space: 0243 Q_EMIT activated(); 0244 return; 0245 0246 default: 0247 break; 0248 } 0249 0250 QLabel::keyPressEvent(e); 0251 } 0252 0253 // ------------------------------------------------------------------------ 0254 0255 DSqueezedClickLabel::DSqueezedClickLabel(QWidget* const parent) 0256 : DAdjustableLabel(parent) 0257 { 0258 setCursor(Qt::PointingHandCursor); 0259 } 0260 0261 DSqueezedClickLabel::DSqueezedClickLabel(const QString& text, QWidget* const parent) 0262 : DAdjustableLabel(parent) 0263 { 0264 setAdjustedText(text); 0265 setCursor(Qt::PointingHandCursor); 0266 } 0267 0268 DSqueezedClickLabel::~DSqueezedClickLabel() 0269 { 0270 } 0271 0272 void DSqueezedClickLabel::mouseReleaseEvent(QMouseEvent* event) 0273 { 0274 QLabel::mouseReleaseEvent(event); 0275 0276 if (event->button() == Qt::LeftButton) 0277 { 0278 Q_EMIT leftClicked(); 0279 Q_EMIT activated(); 0280 event->accept(); 0281 } 0282 } 0283 0284 void DSqueezedClickLabel::mousePressEvent(QMouseEvent* event) 0285 { 0286 QLabel::mousePressEvent(event); 0287 0288 /* 0289 * In some contexts, like QGraphicsView, there will be no 0290 * release event if the press event was not accepted. 0291 */ 0292 if (event->button() == Qt::LeftButton) 0293 { 0294 event->accept(); 0295 } 0296 } 0297 0298 void DSqueezedClickLabel::keyPressEvent(QKeyEvent* e) 0299 { 0300 switch (e->key()) 0301 { 0302 case Qt::Key_Down: 0303 case Qt::Key_Right: 0304 case Qt::Key_Space: 0305 Q_EMIT activated(); 0306 return; 0307 0308 default: 0309 break; 0310 } 0311 0312 QLabel::keyPressEvent(e); 0313 } 0314 0315 // ------------------------------------------------------------------------ 0316 0317 DArrowClickLabel::DArrowClickLabel(QWidget* const parent) 0318 : QWidget(parent), 0319 m_arrowType(Qt::DownArrow) 0320 { 0321 setCursor(Qt::PointingHandCursor); 0322 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); 0323 m_size = 8; 0324 m_margin = 2; 0325 } 0326 0327 void DArrowClickLabel::setArrowType(Qt::ArrowType type) 0328 { 0329 m_arrowType = type; 0330 update(); 0331 } 0332 0333 DArrowClickLabel::~DArrowClickLabel() 0334 { 0335 } 0336 0337 Qt::ArrowType DArrowClickLabel::arrowType() const 0338 { 0339 return m_arrowType; 0340 } 0341 0342 void DArrowClickLabel::mousePressEvent(QMouseEvent* event) 0343 { 0344 /* 0345 * In some contexts, like QGraphicsView, there will be no 0346 * release event if the press event was not accepted. 0347 */ 0348 if (event->button() == Qt::LeftButton) 0349 { 0350 event->accept(); 0351 } 0352 } 0353 0354 void DArrowClickLabel::mouseReleaseEvent(QMouseEvent* event) 0355 { 0356 if (event->button() == Qt::LeftButton) 0357 { 0358 Q_EMIT leftClicked(); 0359 } 0360 } 0361 0362 void DArrowClickLabel::paintEvent(QPaintEvent*) 0363 { 0364 QPainter p(this); 0365 0366 QStyleOptionFrame opt; 0367 opt.initFrom(this); 0368 opt.lineWidth = 2; 0369 opt.midLineWidth = 0; 0370 0371 /* 0372 p.fillRect( rect(), palette().brush( QPalette::Window ) ); 0373 style()->drawPrimitive( QStyle::PE_Frame, &opt, &p, this); 0374 */ 0375 0376 if (m_arrowType == Qt::NoArrow) 0377 { 0378 return; 0379 } 0380 0381 if ((width() < (m_size + m_margin)) || (height() < (m_size + m_margin))) 0382 { 0383 return; // don't draw arrows if we are too small 0384 } 0385 0386 unsigned int x = 0; 0387 unsigned int y = 0; 0388 0389 if (m_arrowType == Qt::DownArrow) 0390 { 0391 x = (width() - m_size) / 2; 0392 y = height() - (m_size + m_margin); 0393 } 0394 else if (m_arrowType == Qt::UpArrow) 0395 { 0396 x = (width() - m_size) / 2; 0397 y = m_margin; 0398 } 0399 else if (m_arrowType == Qt::RightArrow) 0400 { 0401 x = width() - (m_size + m_margin); 0402 y = (height() - m_size) / 2; 0403 } 0404 else // arrowType == LeftArrow 0405 { 0406 x = m_margin; 0407 y = (height() - m_size) / 2; 0408 } 0409 0410 /* 0411 if (isDown()) 0412 { 0413 ++x; 0414 ++y; 0415 } 0416 */ 0417 0418 QStyle::PrimitiveElement e = QStyle::PE_IndicatorArrowLeft; 0419 0420 switch (m_arrowType) 0421 { 0422 case Qt::LeftArrow: 0423 e = QStyle::PE_IndicatorArrowLeft; 0424 break; 0425 0426 case Qt::RightArrow: 0427 e = QStyle::PE_IndicatorArrowRight; 0428 break; 0429 0430 case Qt::UpArrow: 0431 e = QStyle::PE_IndicatorArrowUp; 0432 break; 0433 0434 case Qt::DownArrow: 0435 e = QStyle::PE_IndicatorArrowDown; 0436 break; 0437 0438 case Qt::NoArrow: 0439 break; 0440 } 0441 0442 opt.state |= QStyle::State_Enabled; 0443 opt.rect = QRect( x, y, m_size, m_size); 0444 0445 style()->drawPrimitive( e, &opt, &p, this ); 0446 } 0447 0448 QSize DArrowClickLabel::sizeHint() const 0449 { 0450 return QSize(m_size + 2*m_margin, m_size + 2*m_margin); 0451 } 0452 0453 // ------------------------------------------------------------------------ 0454 0455 class Q_DECL_HIDDEN DLabelExpander::Private 0456 { 0457 0458 public: 0459 0460 explicit Private() 0461 : expandByDefault (true), 0462 checkBox (nullptr), 0463 pixmapLabel (nullptr), 0464 btn (nullptr), 0465 containerWidget (nullptr), 0466 grid (nullptr), 0467 line (nullptr), 0468 hbox (nullptr), 0469 arrow (nullptr), 0470 clickLabel (nullptr) 0471 { 0472 } 0473 0474 bool expandByDefault; 0475 0476 QCheckBox* checkBox; 0477 QLabel* pixmapLabel; 0478 QToolButton* btn; 0479 QWidget* containerWidget; 0480 QGridLayout* grid; 0481 0482 DLineWidget* line; 0483 QWidget* hbox; 0484 0485 DArrowClickLabel* arrow; 0486 DClickLabel* clickLabel; 0487 }; 0488 0489 DLabelExpander::DLabelExpander(QWidget* const parent) 0490 : QWidget(parent), 0491 d (new Private) 0492 { 0493 const int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0494 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing)); 0495 0496 d->grid = new QGridLayout(this); 0497 d->line = new DLineWidget(Qt::Horizontal, this); 0498 d->hbox = new QWidget(this); 0499 d->arrow = new DArrowClickLabel(d->hbox); 0500 d->checkBox = new QCheckBox(d->hbox); 0501 d->pixmapLabel = new QLabel(d->hbox); 0502 d->clickLabel = new DClickLabel(d->hbox); 0503 d->btn = new QToolButton(d->hbox); 0504 0505 QHBoxLayout* const hlay = new QHBoxLayout(d->hbox); 0506 hlay->addWidget(d->arrow); 0507 hlay->addWidget(d->checkBox); 0508 hlay->addWidget(d->pixmapLabel); 0509 hlay->addWidget(d->clickLabel, 10); 0510 hlay->addWidget(d->btn); 0511 hlay->setContentsMargins(QMargins()); 0512 hlay->setSpacing(spacing); 0513 0514 d->pixmapLabel->installEventFilter(this); 0515 d->pixmapLabel->setCursor(Qt::PointingHandCursor); 0516 0517 d->hbox->setCursor(Qt::PointingHandCursor); 0518 setCheckBoxVisible(false); 0519 setButtonVisible(false); 0520 0521 d->grid->addWidget(d->line, 0, 0, 1, 3); 0522 d->grid->addWidget(d->hbox, 1, 0, 1, 3); 0523 d->grid->setColumnStretch(2, 10); 0524 d->grid->setContentsMargins(spacing, spacing, spacing, spacing); 0525 d->grid->setSpacing(spacing); 0526 0527 connect(d->arrow, &DArrowClickLabel::leftClicked, 0528 this, &DLabelExpander::slotToggleContainer); 0529 0530 connect(d->clickLabel, &DClickLabel::activated, 0531 this, &DLabelExpander::slotToggleContainer); 0532 0533 connect(d->checkBox, &QCheckBox::toggled, 0534 this, &DLabelExpander::signalToggled); 0535 0536 connect(d->btn, &QToolButton::pressed, 0537 this, &DLabelExpander::signalButtonPressed); 0538 } 0539 0540 DLabelExpander::~DLabelExpander() 0541 { 0542 delete d; 0543 } 0544 0545 void DLabelExpander::setCheckBoxVisible(bool b) 0546 { 0547 d->checkBox->setVisible(b); 0548 } 0549 0550 bool DLabelExpander::checkBoxIsVisible() const 0551 { 0552 return d->checkBox->isVisible(); 0553 } 0554 0555 void DLabelExpander::setChecked(bool b) 0556 { 0557 d->checkBox->setChecked(b); 0558 } 0559 0560 bool DLabelExpander::isChecked() const 0561 { 0562 return d->checkBox->isChecked(); 0563 } 0564 0565 void DLabelExpander::setLineVisible(bool b) 0566 { 0567 d->line->setVisible(b); 0568 } 0569 0570 bool DLabelExpander::lineIsVisible() const 0571 { 0572 return d->line->isVisible(); 0573 } 0574 0575 void DLabelExpander::setText(const QString& txt) 0576 { 0577 d->clickLabel->setText(QString::fromUtf8("<qt><b>%1</b></qt>").arg(txt)); 0578 } 0579 0580 QString DLabelExpander::text() const 0581 { 0582 return d->clickLabel->text(); 0583 } 0584 0585 void DLabelExpander::setIcon(const QIcon& icon) 0586 { 0587 d->pixmapLabel->setPixmap(icon.pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize))); 0588 } 0589 0590 QIcon DLabelExpander::icon() const 0591 { 0592 0593 #if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)) 0594 0595 return QIcon(d->pixmapLabel->pixmap(Qt::ReturnByValue)); 0596 0597 #else 0598 0599 return QIcon(*d->pixmapLabel->pixmap()); 0600 0601 #endif 0602 0603 } 0604 0605 void DLabelExpander::setButtonVisible(bool b) 0606 { 0607 d->btn->setVisible(b); 0608 } 0609 0610 bool DLabelExpander::buttonIsVisible() const 0611 { 0612 return d->btn->isVisible(); 0613 } 0614 0615 void DLabelExpander::setButtonIcon(const QIcon& icon) 0616 { 0617 d->btn->setIcon(icon); 0618 d->btn->setIconSize(QSize(style()->pixelMetric(QStyle::PM_SmallIconSize), style()->pixelMetric(QStyle::PM_SmallIconSize))); 0619 } 0620 0621 void DLabelExpander::setWidget(QWidget* const widget) 0622 { 0623 if (widget) 0624 { 0625 d->containerWidget = widget; 0626 d->containerWidget->setParent(this); 0627 d->grid->addWidget(d->containerWidget, 2, 0, 1, 3); 0628 } 0629 } 0630 0631 QWidget* DLabelExpander::widget() const 0632 { 0633 return d->containerWidget; 0634 } 0635 0636 void DLabelExpander::setExpandByDefault(bool b) 0637 { 0638 d->expandByDefault = b; 0639 } 0640 0641 bool DLabelExpander::isExpandByDefault() const 0642 { 0643 return d->expandByDefault; 0644 } 0645 0646 void DLabelExpander::setExpanded(bool b) 0647 { 0648 if (d->containerWidget) 0649 { 0650 d->containerWidget->setVisible(b); 0651 0652 if (b) 0653 { 0654 d->arrow->setArrowType(Qt::DownArrow); 0655 } 0656 else 0657 { 0658 d->arrow->setArrowType(Qt::RightArrow); 0659 } 0660 } 0661 0662 Q_EMIT signalExpanded(b); 0663 } 0664 0665 bool DLabelExpander::isExpanded() const 0666 { 0667 return (d->arrow->arrowType() == Qt::DownArrow); 0668 } 0669 0670 void DLabelExpander::slotToggleContainer() 0671 { 0672 if (d->containerWidget) 0673 { 0674 setExpanded(!d->containerWidget->isVisible()); 0675 } 0676 } 0677 0678 bool DLabelExpander::eventFilter(QObject* obj, QEvent* ev) 0679 { 0680 if (obj == d->pixmapLabel) 0681 { 0682 if (ev->type() == QEvent::MouseButtonRelease) 0683 { 0684 slotToggleContainer(); 0685 return false; 0686 } 0687 else 0688 { 0689 return false; 0690 } 0691 } 0692 else 0693 { 0694 // pass the event on to the parent class 0695 0696 return QWidget::eventFilter(obj, ev); 0697 } 0698 } 0699 0700 // ------------------------------------------------------------------------ 0701 0702 class Q_DECL_HIDDEN DExpanderBox::Private 0703 { 0704 public: 0705 0706 explicit Private(DExpanderBox* const box) 0707 : vbox (nullptr), 0708 parent(box) 0709 { 0710 } 0711 0712 void createItem(int index, QWidget* const w, const QIcon& icon, const QString& txt, 0713 const QString& objName, bool expandBydefault) 0714 { 0715 DLabelExpander* const exp = new DLabelExpander(parent->viewport()); 0716 exp->setText(txt); 0717 exp->setIcon(icon.pixmap(QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize))); 0718 exp->setWidget(w); 0719 exp->setLineVisible(!wList.isEmpty()); 0720 exp->setObjectName(objName); 0721 exp->setExpandByDefault(expandBydefault); 0722 0723 if (index >= 0) 0724 { 0725 vbox->insertWidget(index, exp); 0726 wList.insert(index, exp); 0727 } 0728 else 0729 { 0730 vbox->addWidget(exp); 0731 wList.append(exp); 0732 } 0733 0734 parent->connect(exp, SIGNAL(signalExpanded(bool)), 0735 parent, SLOT(slotItemExpanded(bool))); 0736 0737 parent->connect(exp, SIGNAL(signalToggled(bool)), 0738 parent, SLOT(slotItemToggled(bool))); 0739 0740 parent->connect(exp, SIGNAL(signalButtonPressed()), 0741 parent, SLOT(slotItemButtonPressed())); 0742 } 0743 0744 public: 0745 0746 QList<DLabelExpander*> wList; 0747 0748 QVBoxLayout* vbox; 0749 0750 DExpanderBox* parent; 0751 }; 0752 0753 DExpanderBox::DExpanderBox(QWidget* const parent) 0754 : QScrollArea(parent), 0755 d (new Private(this)) 0756 { 0757 setFrameStyle(QFrame::NoFrame); 0758 setWidgetResizable(true); 0759 QWidget* const main = new QWidget(viewport()); 0760 d->vbox = new QVBoxLayout(main); 0761 d->vbox->setSpacing(qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing), 0762 QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing))); 0763 d->vbox->setContentsMargins(QMargins()); 0764 setWidget(main); 0765 0766 setAutoFillBackground(false); 0767 viewport()->setAutoFillBackground(false); 0768 main->setAutoFillBackground(false); 0769 } 0770 0771 DExpanderBox::~DExpanderBox() 0772 { 0773 d->wList.clear(); 0774 delete d; 0775 } 0776 0777 void DExpanderBox::setCheckBoxVisible(int index, bool b) 0778 { 0779 if ((index > d->wList.count()) || (index < 0)) 0780 { 0781 return; 0782 } 0783 0784 d->wList[index]->setCheckBoxVisible(b); 0785 } 0786 0787 bool DExpanderBox::checkBoxIsVisible(int index) const 0788 { 0789 if ((index > d->wList.count()) || (index < 0)) 0790 { 0791 return false; 0792 } 0793 0794 return d->wList[index]->checkBoxIsVisible(); 0795 } 0796 0797 void DExpanderBox::setChecked(int index, bool b) 0798 { 0799 if ((index > d->wList.count()) || (index < 0)) 0800 { 0801 return; 0802 } 0803 0804 d->wList[index]->setChecked(b); 0805 } 0806 0807 bool DExpanderBox::isChecked(int index) const 0808 { 0809 if ((index > d->wList.count()) || (index < 0)) 0810 { 0811 return false; 0812 } 0813 0814 return d->wList[index]->isChecked(); 0815 } 0816 0817 void DExpanderBox::addItem(QWidget* const w, const QIcon& icon, const QString& txt, 0818 const QString& objName, bool expandBydefault) 0819 { 0820 d->createItem(-1, w, icon, txt, objName, expandBydefault); 0821 } 0822 0823 void DExpanderBox::addItem(QWidget* const w, const QString& txt, 0824 const QString& objName, bool expandBydefault) 0825 { 0826 addItem(w, QIcon(), txt, objName, expandBydefault); 0827 } 0828 0829 void DExpanderBox::addStretch() 0830 { 0831 d->vbox->addStretch(10); 0832 } 0833 0834 void DExpanderBox::insertItem(int index, QWidget* const w, const QIcon& icon, const QString& txt, 0835 const QString& objName, bool expandBydefault) 0836 { 0837 d->createItem(index, w, icon, txt, objName, expandBydefault); 0838 } 0839 0840 void DExpanderBox::slotItemExpanded(bool b) 0841 { 0842 DLabelExpander* const exp = dynamic_cast<DLabelExpander*>(sender()); 0843 0844 if (exp) 0845 { 0846 int index = indexOf(exp); 0847 Q_EMIT signalItemExpanded(index, b); 0848 } 0849 } 0850 0851 void DExpanderBox::slotItemButtonPressed() 0852 { 0853 DLabelExpander* const exp = dynamic_cast<DLabelExpander*>(sender()); 0854 0855 if (exp) 0856 { 0857 int index = indexOf(exp); 0858 Q_EMIT signalItemButtonPressed(index); 0859 } 0860 } 0861 0862 void DExpanderBox::slotItemToggled(bool b) 0863 { 0864 DLabelExpander* const exp = dynamic_cast<DLabelExpander*>(sender()); 0865 0866 if (exp) 0867 { 0868 int index = indexOf(exp); 0869 Q_EMIT signalItemToggled(index, b); 0870 } 0871 } 0872 0873 void DExpanderBox::insertItem(int index, QWidget* const w, const QString& txt, 0874 const QString& objName, bool expandBydefault) 0875 { 0876 insertItem(index, w, QIcon(), txt, objName, expandBydefault); 0877 } 0878 0879 void DExpanderBox::insertStretch(int index) 0880 { 0881 d->vbox->insertStretch(index, 10); 0882 } 0883 0884 void DExpanderBox::removeItem(int index) 0885 { 0886 if ((index > d->wList.count()) || (index < 0)) 0887 { 0888 return; 0889 } 0890 0891 d->wList[index]->hide(); 0892 d->wList.removeAt(index); 0893 } 0894 0895 void DExpanderBox::setItemText(int index, const QString& txt) 0896 { 0897 if ((index > d->wList.count()) || (index < 0)) 0898 { 0899 return; 0900 } 0901 0902 d->wList[index]->setText(txt); 0903 } 0904 0905 QString DExpanderBox::itemText(int index) const 0906 { 0907 if ((index > d->wList.count()) || (index < 0)) 0908 { 0909 return QString(); 0910 } 0911 0912 return d->wList[index]->text(); 0913 } 0914 0915 void DExpanderBox::setItemIcon(int index, const QIcon& icon) 0916 { 0917 if ((index > d->wList.count()) || (index < 0)) 0918 { 0919 return; 0920 } 0921 0922 d->wList[index]->setIcon(icon.pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize))); 0923 } 0924 0925 QIcon DExpanderBox::itemIcon(int index) const 0926 { 0927 if ((index > d->wList.count()) || (index < 0)) 0928 { 0929 return QIcon(); 0930 } 0931 0932 return d->wList[index]->icon(); 0933 } 0934 0935 void DExpanderBox::setButtonVisible(int index, bool b) 0936 { 0937 if ((index > d->wList.count()) || (index < 0)) 0938 { 0939 return; 0940 } 0941 0942 d->wList[index]->setButtonVisible(b); 0943 } 0944 0945 bool DExpanderBox::buttonIsVisible(int index) const 0946 { 0947 if ((index > d->wList.count()) || (index < 0)) 0948 { 0949 return false; 0950 } 0951 0952 return d->wList[index]->buttonIsVisible(); 0953 } 0954 0955 void DExpanderBox::setButtonIcon(int index, const QIcon& icon) 0956 { 0957 if ((index > d->wList.count()) || (index < 0)) 0958 { 0959 return; 0960 } 0961 0962 d->wList[index]->setButtonIcon(icon); 0963 } 0964 0965 int DExpanderBox::count() const 0966 { 0967 return d->wList.count(); 0968 } 0969 0970 void DExpanderBox::setItemToolTip(int index, const QString& tip) 0971 { 0972 if ((index > d->wList.count()) || (index < 0)) 0973 { 0974 return; 0975 } 0976 0977 d->wList[index]->setToolTip(tip); 0978 } 0979 0980 QString DExpanderBox::itemToolTip(int index) const 0981 { 0982 if ((index > d->wList.count()) || (index < 0)) 0983 { 0984 return QString(); 0985 } 0986 0987 return d->wList[index]->toolTip(); 0988 } 0989 0990 void DExpanderBox::setItemEnabled(int index, bool enabled) 0991 { 0992 if ((index > d->wList.count()) || (index < 0)) 0993 { 0994 return; 0995 } 0996 0997 d->wList[index]->setEnabled(enabled); 0998 } 0999 1000 bool DExpanderBox::isItemEnabled(int index) const 1001 { 1002 if ((index > d->wList.count()) || (index < 0)) 1003 { 1004 return false; 1005 } 1006 1007 return d->wList[index]->isEnabled(); 1008 } 1009 1010 DLabelExpander* DExpanderBox::widget(int index) const 1011 { 1012 if ((index > d->wList.count()) || (index < 0)) 1013 { 1014 return nullptr; 1015 } 1016 1017 return d->wList[index]; 1018 } 1019 1020 int DExpanderBox::indexOf(DLabelExpander* const widget) const 1021 { 1022 for (int i = 0 ; i < count() ; ++i) 1023 { 1024 DLabelExpander* const exp = d->wList[i]; 1025 1026 if (widget == exp) 1027 { 1028 return i; 1029 } 1030 } 1031 1032 return -1; 1033 } 1034 1035 void DExpanderBox::setItemExpanded(int index, bool b) 1036 { 1037 if ((index > d->wList.count()) || (index < 0)) 1038 { 1039 return; 1040 } 1041 1042 DLabelExpander* const exp = d->wList[index]; 1043 1044 if (!exp) return; 1045 1046 exp->setExpanded(b); 1047 } 1048 1049 bool DExpanderBox::isItemExpanded(int index) const 1050 { 1051 if ((index > d->wList.count()) || (index < 0)) 1052 { 1053 return false; 1054 } 1055 1056 DLabelExpander* const exp = d->wList[index]; 1057 1058 if (!exp) 1059 { 1060 return false; 1061 } 1062 1063 return (exp->isExpanded()); 1064 } 1065 1066 void DExpanderBox::readSettings(KConfigGroup& group) 1067 { 1068 for (int i = 0 ; i < count() ; ++i) 1069 { 1070 DLabelExpander* const exp = d->wList[i]; 1071 1072 if (exp) 1073 { 1074 exp->setExpanded(group.readEntry(QString::fromUtf8("%1 Expanded").arg(exp->objectName()), 1075 exp->isExpandByDefault())); 1076 } 1077 } 1078 } 1079 1080 void DExpanderBox::writeSettings(KConfigGroup& group) 1081 { 1082 for (int i = 0 ; i < count() ; ++i) 1083 { 1084 DLabelExpander* const exp = d->wList[i]; 1085 1086 if (exp) 1087 { 1088 group.writeEntry(QString::fromUtf8("%1 Expanded").arg(exp->objectName()), 1089 exp->isExpanded()); 1090 } 1091 } 1092 } 1093 1094 // ------------------------------------------------------------------------ 1095 1096 DExpanderBoxExclusive::DExpanderBoxExclusive(QWidget* const parent) 1097 : DExpanderBox(parent) 1098 { 1099 setIsToolBox(true); 1100 } 1101 1102 DExpanderBoxExclusive::~DExpanderBoxExclusive() 1103 { 1104 } 1105 1106 void DExpanderBoxExclusive::slotItemExpanded(bool b) 1107 { 1108 DLabelExpander* const exp = dynamic_cast<DLabelExpander*>(sender()); 1109 1110 if (!exp) 1111 { 1112 return; 1113 } 1114 1115 if (isToolBox() && b) 1116 { 1117 int item = 0; 1118 1119 while (item < count()) 1120 { 1121 if (isItemExpanded(item) && (item != indexOf(exp))) 1122 { 1123 setItemExpanded(item, false); 1124 } 1125 1126 item++; 1127 } 1128 } 1129 1130 Q_EMIT signalItemExpanded(indexOf(exp), b); 1131 } 1132 1133 void DExpanderBoxExclusive::setIsToolBox(bool b) 1134 { 1135 m_toolbox = b; 1136 } 1137 1138 bool DExpanderBoxExclusive::isToolBox() const 1139 { 1140 return (m_toolbox); 1141 } 1142 1143 } // namespace Digikam 1144 1145 #include "moc_dexpanderbox.cpp"