Krita Source Code Documentation
Loading...
Searching...
No Matches
rexpanderbox.cpp
Go to the documentation of this file.
1
30#include "rexpanderbox.h"
31
32// Qt includes
33
34#include <QApplication>
35#include <QMouseEvent>
36#include <QPainter>
37#include <QStyle>
38#include <QStyleOption>
39#include <QGridLayout>
40#include <QHBoxLayout>
41#include <QCheckBox>
42
43// KDE includes
44
45#include <kconfiggroup.h>
46#include <klocalizedstring.h>
47
48namespace KDcrawIface
49{
50
51RClickLabel::RClickLabel(QWidget* const parent)
52 : QLabel(parent)
53{
54 setCursor(Qt::PointingHandCursor);
55}
56
57RClickLabel::RClickLabel(const QString& text, QWidget* const parent)
58 : QLabel(text, parent)
59{
60 setCursor(Qt::PointingHandCursor);
61}
62
66
67void RClickLabel::mousePressEvent(QMouseEvent* event)
68{
69 QLabel::mousePressEvent(event);
70
71 /*
72 * In some contexts, like QGraphicsView, there will be no
73 * release event if the press event was not accepted.
74 */
75 if (event->button() == Qt::LeftButton)
76 {
77 event->accept();
78 }
79}
80
81void RClickLabel::mouseReleaseEvent(QMouseEvent* event)
82{
83 QLabel::mouseReleaseEvent(event);
84
85 if (event->button() == Qt::LeftButton)
86 {
87 Q_EMIT leftClicked();
88 Q_EMIT activated();
89 event->accept();
90 }
91}
92
94{
95 switch (e->key())
96 {
97 case Qt::Key_Down:
98 case Qt::Key_Right:
99 case Qt::Key_Space:
100 Q_EMIT activated();
101 return;
102 default:
103 break;
104 }
105
106 QLabel::keyPressEvent(e);
107}
108
109// ------------------------------------------------------------------------
110
112 : RAdjustableLabel(parent)
113{
114 setCursor(Qt::PointingHandCursor);
115}
116
117RSqueezedClickLabel::RSqueezedClickLabel(const QString& text, QWidget* const parent)
118 : RAdjustableLabel(parent)
119{
121 setCursor(Qt::PointingHandCursor);
122}
123
127
129{
130 QLabel::mouseReleaseEvent(event);
131
132 if (event->button() == Qt::LeftButton)
133 {
134 Q_EMIT leftClicked();
135 Q_EMIT activated();
136 event->accept();
137 }
138}
139
141{
142 QLabel::mousePressEvent(event);
143
144 /*
145 * In some contexts, like QGraphicsView, there will be no
146 * release event if the press event was not accepted.
147 */
148 if (event->button() == Qt::LeftButton)
149 {
150 event->accept();
151 }
152}
153
155{
156 switch (e->key())
157 {
158 case Qt::Key_Down:
159 case Qt::Key_Right:
160 case Qt::Key_Space:
161 Q_EMIT activated();
162 return;
163 default:
164 break;
165 }
166
167 QLabel::keyPressEvent(e);
168}
169
170// ------------------------------------------------------------------------
171
173 : QWidget(parent), m_arrowType(Qt::DownArrow)
174{
175 setCursor(Qt::PointingHandCursor);
176 setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
177 m_size = 8;
178 m_margin = 2;
179}
180
181void RArrowClickLabel::setArrowType(Qt::ArrowType type)
182{
183 m_arrowType = type;
184 update();
185}
186
190
191Qt::ArrowType RArrowClickLabel::arrowType() const
192{
193 return m_arrowType;
194}
195
196void RArrowClickLabel::mousePressEvent(QMouseEvent* event)
197{
198 /*
199 * In some contexts, like QGraphicsView, there will be no
200 * release event if the press event was not accepted.
201 */
202 if (event->button() == Qt::LeftButton)
203 {
204 event->accept();
205 }
206}
207
209{
210 if (event->button() == Qt::LeftButton)
211 {
212 Q_EMIT leftClicked();
213 }
214}
215
217{
218 // Inspired by karrowbutton.cpp,
219 // Copyright (C) 2001 Frerich Raabe <raabe@kde.org>
220
221 QPainter p(this);
222
223 QStyleOptionFrame opt;
224 opt.initFrom(this);
225 opt.lineWidth = 2;
226 opt.midLineWidth = 0;
227
228 /*
229 p.fillRect( rect(), palette().brush( QPalette::Window ) );
230 style()->drawPrimitive( QStyle::PE_Frame, &opt, &p, this);
231 */
232
233 if (m_arrowType == Qt::NoArrow)
234 return;
235
236 if (width() < m_size + m_margin || height() < m_size + m_margin)
237 return; // don't draw arrows if we are too small
238
239 unsigned int x = 0, y = 0;
240 if (m_arrowType == Qt::DownArrow)
241 {
242 x = (width() - m_size) / 2;
243 y = height() - (m_size + m_margin);
244 }
245 else if (m_arrowType == Qt::UpArrow)
246 {
247 x = (width() - m_size) / 2;
248 y = m_margin;
249 }
250 else if (m_arrowType == Qt::RightArrow)
251 {
252 x = width() - (m_size + m_margin);
253 y = (height() - m_size) / 2;
254 }
255 else // arrowType == LeftArrow
256 {
257 x = m_margin;
258 y = (height() - m_size) / 2;
259 }
260
261/*
262 if (isDown())
263 {
264 ++x;
265 ++y;
266 }
267*/
268
269 QStyle::PrimitiveElement e = QStyle::PE_IndicatorArrowLeft;
270
271 switch (m_arrowType)
272 {
273 case Qt::LeftArrow:
274 e = QStyle::PE_IndicatorArrowLeft;
275 break;
276 case Qt::RightArrow:
277 e = QStyle::PE_IndicatorArrowRight;
278 break;
279 case Qt::UpArrow:
280 e = QStyle::PE_IndicatorArrowUp;
281 break;
282 case Qt::DownArrow:
283 e = QStyle::PE_IndicatorArrowDown;
284 break;
285 case Qt::NoArrow:
286 break;
287 }
288
289 opt.state |= QStyle::State_Enabled;
290 opt.rect = QRect( x, y, m_size, m_size);
291
292 style()->drawPrimitive( e, &opt, &p, this );
293}
294
296{
297 return QSize(m_size + 2*m_margin, m_size + 2*m_margin);
298}
299
300// ------------------------------------------------------------------------
301
302class Q_DECL_HIDDEN RLabelExpander::Private
303{
304
305public:
306
308 {
309 clickLabel = 0;
310 containerWidget = 0;
311 pixmapLabel = 0;
312 grid = 0;
313 arrow = 0;
314 line = 0;
315 hbox = 0;
316 checkBox = 0;
317 expandByDefault = true;
318 }
319
321
322 QCheckBox* checkBox;
323 QLabel* pixmapLabel;
325 QGridLayout* grid;
326
328 QWidget* hbox;
329
332};
333
334RLabelExpander::RLabelExpander(QWidget* const parent)
335 : QWidget(parent), d(new Private)
336{
337 d->grid = new QGridLayout(this);
338 d->line = new RLineWidget(Qt::Horizontal, this);
339 d->hbox = new QWidget(this);
340 d->arrow = new RArrowClickLabel(d->hbox);
341 d->checkBox = new QCheckBox(d->hbox);
342 d->pixmapLabel = new QLabel(d->hbox);
343 d->clickLabel = new RClickLabel(d->hbox);
344
345 QHBoxLayout* const hlay = new QHBoxLayout(d->hbox);
346 hlay->addWidget(d->arrow);
347 hlay->addWidget(d->checkBox);
348 hlay->addWidget(d->pixmapLabel);
349 hlay->addWidget(d->clickLabel, 10);
350 hlay->setContentsMargins(0, 0, 0, 0);
351
352 const int styleSpacing = QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing);
353 hlay->setSpacing(styleSpacing);
354
355 d->pixmapLabel->installEventFilter(this);
356 d->pixmapLabel->setCursor(Qt::PointingHandCursor);
357
358 d->hbox->setCursor(Qt::PointingHandCursor);
359 setCheckBoxVisible(false);
360
361 d->grid->addWidget(d->line, 0, 0, 1, 3);
362 d->grid->addWidget(d->hbox, 1, 0, 1, 3);
363 d->grid->setColumnStretch(2, 10);
364 d->grid->setContentsMargins(styleSpacing, styleSpacing, styleSpacing, styleSpacing);
365 d->grid->setSpacing(styleSpacing);
366
369
370 connect(d->clickLabel, &RClickLabel::activated,
372
373 connect(d->checkBox, &QCheckBox::toggled,
375}
376
378{
379 delete d;
380}
381
383{
384 d->checkBox->setVisible(b);
385}
386
388{
389 return d->checkBox->isVisible();
390}
391
393{
394 d->checkBox->setChecked(b);
395}
396
398{
399 return d->checkBox->isChecked();
400}
401
403{
404 d->line->setVisible(b);
405}
406
408{
409 return d->line->isVisible();
410}
411
412void RLabelExpander::setText(const QString& txt)
413{
414 d->clickLabel->setText(QString("<qt><b>%1</b></qt>").arg(txt));
415}
416
417QString RLabelExpander::text() const
418{
419 return d->clickLabel->text();
420}
421
422void RLabelExpander::setIcon(const QIcon& icon)
423{
424 d->pixmapLabel->setPixmap(icon.pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize)));
425}
426
428{
429#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
430 return QIcon(*d->pixmapLabel->pixmap());
431#else
432 return QIcon(d->pixmapLabel->pixmap());
433#endif
434}
435
436void RLabelExpander::setWidget(QWidget* const widget)
437{
438 if (widget)
439 {
440 d->containerWidget = widget;
441 d->containerWidget->setParent(this);
442 d->grid->addWidget(d->containerWidget, 2, 0, 1, 3);
443 }
444}
445
447{
448 return d->containerWidget;
449}
450
452{
453 d->expandByDefault = b;
454}
455
457{
458 return d->expandByDefault;
459}
460
462{
463 if (d->containerWidget)
464 {
465 d->containerWidget->setVisible(b);
466
467 if (b)
468 d->arrow->setArrowType(Qt::DownArrow);
469 else
470 d->arrow->setArrowType(Qt::RightArrow);
471 }
472
473 Q_EMIT signalExpanded(b);
474}
475
477{
478 return (d->arrow->arrowType() == Qt::DownArrow);
479}
480
482{
483 if (d->containerWidget)
484 setExpanded(!d->containerWidget->isVisible());
485}
486
487bool RLabelExpander::eventFilter(QObject* obj, QEvent* ev)
488{
489 if ( obj == d->pixmapLabel)
490 {
491 if ( ev->type() == QEvent::MouseButtonRelease)
492 {
494 return false;
495 }
496 else
497 {
498 return false;
499 }
500 }
501 else
502 {
503 // pass the event on to the parent class
504 return QWidget::eventFilter(obj, ev);
505 }
506}
507
508// ------------------------------------------------------------------------
509
510class Q_DECL_HIDDEN RExpanderBox::Private
511{
512public:
513
515 {
516 parent = box;
517 vbox = 0;
518 }
519
520 void createItem(int index, QWidget* const w, const QIcon& icon, const QString& txt,
521 const QString& objName, bool expandBydefault)
522 {
523 RLabelExpander* const exp = new RLabelExpander(parent->viewport());
524 exp->setText(txt);
525 exp->setIcon(icon.pixmap(QApplication::style()->pixelMetric(QStyle::PM_SmallIconSize)));
526 exp->setWidget(w);
527 exp->setLineVisible(!wList.isEmpty());
528 exp->setObjectName(objName);
529 exp->setExpandByDefault(expandBydefault);
530
531 if (index >= 0)
532 {
533 vbox->insertWidget(index, exp);
534 wList.insert(index, exp);
535 }
536 else
537 {
538 vbox->addWidget(exp);
539 wList.append(exp);
540 }
541
542 parent->connect(exp, SIGNAL(signalExpanded(bool)),
543 parent, SLOT(slotItemExpanded(bool)));
544
545 parent->connect(exp, SIGNAL(signalToggled(bool)),
546 parent, SLOT(slotItemToggled(bool)));
547 }
548
549public:
550
552
553 QVBoxLayout* vbox;
554
556};
557
558RExpanderBox::RExpanderBox(QWidget* const parent)
559 : QScrollArea(parent), d(new Private(this))
560{
561 setFrameStyle(QFrame::NoFrame);
562 setWidgetResizable(true);
563 QWidget* const main = new QWidget(viewport());
564 d->vbox = new QVBoxLayout(main);
565 d->vbox->setContentsMargins(0, 0, 0, 0);
566 d->vbox->setSpacing(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing));
567 setWidget(main);
568
569 setAutoFillBackground(false);
570 viewport()->setAutoFillBackground(false);
571 main->setAutoFillBackground(false);
572}
573
575{
576 d->wList.clear();
577 delete d;
578}
579
580void RExpanderBox::setCheckBoxVisible(int index, bool b)
581{
582 if (index > d->wList.count() || index < 0) return;
583 d->wList[index]->setCheckBoxVisible(b);
584}
585
587{
588 if (index > d->wList.count() || index < 0) return false;
589 return d->wList[index]->checkBoxIsVisible();
590}
591
592void RExpanderBox::setChecked(int index, bool b)
593{
594 if (index > d->wList.count() || index < 0) return;
595 d->wList[index]->setChecked(b);
596}
597
598bool RExpanderBox::isChecked(int index) const
599{
600 if (index > d->wList.count() || index < 0) return false;
601 return d->wList[index]->isChecked();
602}
603
604void RExpanderBox::addItem(QWidget* const w, const QIcon& icon, const QString& txt,
605 const QString& objName, bool expandBydefault)
606{
607 d->createItem(-1, w, icon, txt, objName, expandBydefault);
608}
609
610void RExpanderBox::addItem(QWidget* const w, const QString& txt,
611 const QString& objName, bool expandBydefault)
612{
613 addItem(w, QIcon(), txt, objName, expandBydefault);
614}
615
617{
618 d->vbox->addStretch(10);
619}
620
621void RExpanderBox::insertItem(int index, QWidget* const w, const QIcon& icon, const QString& txt,
622 const QString& objName, bool expandBydefault)
623{
624 d->createItem(index, w, icon, txt, objName, expandBydefault);
625}
626
628{
629 RLabelExpander* const exp = dynamic_cast<RLabelExpander*>(sender());
630
631 if (exp)
632 {
633 int index = indexOf(exp);
634 Q_EMIT signalItemExpanded(index, b);
635 }
636}
637
639{
640 RLabelExpander* const exp = dynamic_cast<RLabelExpander*>(sender());
641
642 if (exp)
643 {
644 int index = indexOf(exp);
645 Q_EMIT signalItemToggled(index, b);
646 }
647}
648
649void RExpanderBox::insertItem(int index, QWidget* const w, const QString& txt,
650 const QString& objName, bool expandBydefault)
651{
652 insertItem(index, w, QIcon(), txt, objName, expandBydefault);
653}
654
656{
657 d->vbox->insertStretch(index, 10);
658}
659
661{
662 if (index > d->wList.count() || index < 0) return;
663 d->wList[index]->hide();
664 d->wList.removeAt(index);
665}
666
667void RExpanderBox::setItemText(int index, const QString& txt)
668{
669 if (index > d->wList.count() || index < 0) return;
670 d->wList[index]->setText(txt);
671}
672
673QString RExpanderBox::itemText(int index) const
674{
675 if (index > d->wList.count() || index < 0) return QString();
676 return d->wList[index]->text();
677}
678
679void RExpanderBox::setItemIcon(int index, const QIcon& icon)
680{
681 if (index > d->wList.count() || index < 0) return;
682 d->wList[index]->setIcon(icon.pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize)));
683}
684
685QIcon RExpanderBox::itemIcon(int index) const
686{
687 if (index > d->wList.count() || index < 0) return QIcon();
688 return d->wList[index]->icon();
689}
690
692{
693 return d->wList.count();
694}
695
696void RExpanderBox::setItemToolTip(int index, const QString& tip)
697{
698 if (index > d->wList.count() || index < 0) return;
699 d->wList[index]->setToolTip(tip);
700}
701
702QString RExpanderBox::itemToolTip(int index) const
703{
704 if (index > d->wList.count() || index < 0) return QString();
705 return d->wList[index]->toolTip();
706}
707
708void RExpanderBox::setItemEnabled(int index, bool enabled)
709{
710 if (index > d->wList.count() || index < 0) return;
711 d->wList[index]->setEnabled(enabled);
712}
713
714bool RExpanderBox::isItemEnabled(int index) const
715{
716 if (index > d->wList.count() || index < 0) return false;
717 return d->wList[index]->isEnabled();
718}
719
721{
722 if (index > d->wList.count() || index < 0) return 0;
723 return d->wList[index];
724}
725
726int RExpanderBox::indexOf(RLabelExpander* const widget) const
727{
728 for (int i = 0 ; i < count(); ++i)
729 {
730 RLabelExpander* const exp = d->wList[i];
731
732 if (widget == exp)
733 return i;
734 }
735 return -1;
736}
737
738void RExpanderBox::setItemExpanded(int index, bool b)
739{
740 if (index > d->wList.count() || index < 0) return;
741
742 RLabelExpander* const exp = d->wList[index];
743
744 if (!exp) return;
745
746 exp->setExpanded(b);
747}
748
749bool RExpanderBox::isItemExpanded(int index) const
750{
751 if (index > d->wList.count() || index < 0) return false;
752
753 RLabelExpander* const exp = d->wList[index];
754
755 if (!exp) return false;
756
757 return (exp->isExpanded());
758}
759
760void RExpanderBox::readSettings(KConfigGroup& group)
761{
762 for (int i = 0 ; i < count(); ++i)
763 {
764 RLabelExpander* const exp = d->wList[i];
765
766 if (exp)
767 {
768 exp->setExpanded(group.readEntry(QString("%1 Expanded").arg(exp->objectName()),
769 exp->isExpandByDefault()));
770 }
771 }
772}
773
774void RExpanderBox::writeSettings(KConfigGroup& group)
775{
776 for (int i = 0 ; i < count(); ++i)
777 {
778 RLabelExpander* const exp = d->wList[i];
779
780 if (exp)
781 {
782 group.writeEntry(QString("%1 Expanded").arg(exp->objectName()),
783 exp->isExpanded());
784 }
785 }
786}
787
788// ------------------------------------------------------------------------
789
791 : RExpanderBox(parent)
792{
793 setIsToolBox(true);
794}
795
799
801{
802 RLabelExpander* const exp = dynamic_cast<RLabelExpander*>(sender());
803 if (!exp) return;
804
805 if (isToolBox() && b)
806 {
807 int item = 0;
808
809 while (item < count())
810 {
811 if (isItemExpanded(item) && item != indexOf(exp))
812 {
813 setItemExpanded(item, false);
814 }
815
816 item++;
817 }
818 }
819 Q_EMIT signalItemExpanded(indexOf(exp), b);
820}
821
823{
824 m_toolbox = b;
825}
826
828{
829 return (m_toolbox);
830}
831
832} // namespace KDcrawIface
const Params2D p
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void setAdjustedText(const QString &text=QString())
void paintEvent(QPaintEvent *event) override
Qt::ArrowType arrowType() const
void mouseReleaseEvent(QMouseEvent *event) override
QSize sizeHint() const override
void setArrowType(Qt::ArrowType arrowType)
void mousePressEvent(QMouseEvent *event) override
RArrowClickLabel(QWidget *const parent=0)
void mousePressEvent(QMouseEvent *event) override
void activated()
Emitted when activated, by mouse or key press.
void keyPressEvent(QKeyEvent *event) override
void mouseReleaseEvent(QMouseEvent *event) override
RClickLabel(QWidget *const parent=0)
void leftClicked()
Emitted when activated by left mouse click.
RExpanderBoxExclusive(QWidget *const parent=0)
void setChecked(int index, bool b)
virtual void writeSettings(KConfigGroup &group)
virtual void readSettings(KConfigGroup &group)
bool isChecked(int index) const
void setItemText(int index, const QString &txt)
bool isItemEnabled(int index) const
int indexOf(RLabelExpander *const widget) const
void setItemToolTip(int index, const QString &tip)
void addItem(QWidget *const w, const QIcon &icon, const QString &txt, const QString &objName, bool expandBydefault)
bool isItemExpanded(int index) const
void signalItemExpanded(int index, bool b)
RLabelExpander * widget(int index) const
void insertItem(int index, QWidget *const w, const QIcon &icon, const QString &txt, const QString &objName, bool expandBydefault)
QIcon itemIcon(int index) const
void createItem(int index, QWidget *const w, const QIcon &icon, const QString &txt, const QString &objName, bool expandBydefault)
QString itemText(int index) const
void setItemExpanded(int index, bool b)
QString itemToolTip(int index) const
QList< RLabelExpander * > wList
void setItemIcon(int index, const QIcon &icon)
Private(RExpanderBox *const box)
void setCheckBoxVisible(int index, bool b)
void signalItemToggled(int index, bool b)
void setItemEnabled(int index, bool enabled)
void insertStretch(int index)
bool checkBoxIsVisible(int index) const
RExpanderBox(QWidget *const parent=0)
RLabelExpander(QWidget *const parent=0)
bool eventFilter(QObject *obj, QEvent *ev) override
void setWidget(QWidget *const widget)
void setText(const QString &txt)
void setIcon(const QIcon &icon)
void mousePressEvent(QMouseEvent *event) override
RSqueezedClickLabel(QWidget *const parent=0)
void keyPressEvent(QKeyEvent *event) override
void mouseReleaseEvent(QMouseEvent *event) override
int main(int argc, char **argv)
Definition main.cpp:26
A widget to host settings as expander box.