29#include <QStyleOptionGroupBox>
32#include "moc_qgscollapsiblegroupbox.cpp"
34using namespace Qt::StringLiterals;
45 : QGroupBox( title, parent )
50void QgsCollapsibleGroupBoxBasic::init()
78 setFocusPolicy( Qt::StrongFocus );
102 if ( parent() && parent()->parent() )
140 if ( event->modifiers() & ( Qt::AltModifier | Qt::ControlModifier | Qt::ShiftModifier ) &&
titleRect().contains( event->pos() ) && isCheckable() )
147 QGroupBox::mousePressEvent( event );
152 mAltDown = (
event->modifiers() & ( Qt::AltModifier | Qt::ControlModifier ) );
153 mShiftDown = (
event->modifiers() & Qt::ShiftModifier );
166 QGroupBox::mouseReleaseEvent( event );
175 QGroupBox::changeEvent( event );
177 if ( event->type() == QEvent::EnabledChange && isEnabled() )
185 if ( !grp.isEmpty() )
187 tipTxt = tr(
"Ctrl (or Alt)-click to toggle all" ) +
'\n' + tr(
"Shift-click to expand, then collapse others" );
194 QStyleOptionGroupBox box;
195 initStyleOption( &box );
196 return style()->subControlRect( QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxLabel,
this );
239 if (
auto *lParentWidget = parentWidget() )
245 if (
mSyncParent->parentWidget()->objectName() !=
"QgisApp"_L1 )
264 if ( grpbox->syncGroup() ==
syncGroup() && grpbox->isEnabled() )
273 grpbox->setCollapsed(
mShiftDown ?
true : !thisCollapsed );
302 QGroupBox::setStyleSheet( style );
307 setUpdatesEnabled(
false );
311 QStyleOptionGroupBox box;
312 initStyleOption( &box );
313 const QRect rectFrame = style()->subControlRect( QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxFrame,
this );
317 const int marginLeft = 20;
318 const int marginRight = 5;
320 const int offsetStyle = QApplication::style()->objectName().contains(
"macintosh"_L1 ) ? 8 : 0;
321 const int topBuffer = 1 + offsetStyle;
322 int offsetTop = topBuffer;
323 int offsetTopTri = topBuffer;
327 offsetTopTri += ( rectTitle.height() -
mCollapseButton->height() ) / 2;
337 if ( QApplication::style()->objectName().compare(
"oxygen"_L1, Qt::CaseInsensitive ) == 0 )
339 QStyleOptionGroupBox box;
340 initStyleOption( &box );
341 const QRect rectFrame = style()->subControlRect( QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxFrame,
this );
342 const QRect rectCheckBox = style()->subControlRect( QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox,
this );
343 if ( rectFrame.left() <= 0 )
344 offsetLeft = 6 + rectFrame.left();
345 if ( rectFrame.top() <= 0 )
350 offsetTop = ( rectCheckBox.height() / 2 ) - (
mCollapseButton->height() / 2 ) + rectCheckBox.top();
351 offsetTopTri = offsetTop + 1;
355 offsetTop = 6 + rectFrame.top();
356 offsetTopTri = offsetTop;
361 QgsDebugMsgLevel( u
"groupbox: %1 style: %2 offset: left=%3 top=%4 top2=%5"_s.arg( objectName(), QApplication::style()->objectName() ).arg( offsetLeft ).arg( offsetTop ).arg( offsetTopTri ), 5 );
365 if ( QApplication::style()->objectName().contains(
"macintosh"_L1 ) )
367 ss +=
"QgsCollapsibleGroupBoxBasic, QgsCollapsibleGroupBox {"_L1;
368 ss += u
" margin-top: %1px;"_s.arg( topBuffer + rectFrame.top() );
371 ss +=
"QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::title {"_L1;
372 ss +=
" subcontrol-origin: margin;"_L1;
373 ss +=
" subcontrol-position: top left;"_L1;
374 ss += u
" margin-left: %1px;"_s.arg( marginLeft );
375 ss += u
" margin-right: %1px;"_s.arg( marginRight );
376 ss += u
" left: %1px;"_s.arg( offsetLeft );
377 ss += u
" top: %1px;"_s.arg( offsetTop );
378 if ( QApplication::style()->objectName().contains(
"macintosh"_L1 ) )
380 ss +=
" background-color: rgba(0,0,0,0)"_L1;
387 ssd = u
"QgsCollapsibleGroupBoxBasic > QToolButton#%1, QgsCollapsibleGroupBox > QToolButton#%1 {"_s.arg(
mCollapseButton->objectName() );
388 ssd +=
" background-color: rgba(255, 255, 255, 0); border: none;"_L1;
389 ssd += u
"} QgsCollapsibleGroupBoxBasic > QToolButton#%1:focus, QgsCollapsibleGroupBox > QToolButton#%1:focus { border: 1px solid palette(highlight); }"_s.arg(
mCollapseButton->objectName() );
391 if ( offsetLeft != 0 || offsetTopTri != 0 )
393 setUpdatesEnabled(
true );
419 setMaximumHeight( collapse ?
titleRect().bottom() + 6 : 16777215 );
426 QApplication::processEvents();
442 const char *hideKey =
"CollGrpBxHide";
444 QString ss = styleSheet();
453 const auto constChildren = children();
454 for ( QObject *child : constChildren )
456 QWidget *w = qobject_cast<QWidget *>( child );
461 w->setProperty( hideKey,
true );
474 const auto constChildren = children();
475 for ( QObject *child : constChildren )
477 QWidget *w = qobject_cast<QWidget *>( child );
480 if ( w->property( hideKey ).toBool() )
492 , mSettings( settings )
499 , mSettings( settings )
516 mSettings = settings;
517 mDelSettings =
false;
520void QgsCollapsibleGroupBox::init()
524 mDelSettings =
false;
531 mSaveCollapsedState =
true;
534 mSaveCheckedState =
false;
566 if ( objectName().isEmpty() || ( mSettingGroup.isEmpty() && window()->objectName().isEmpty() ) )
571 QString
saveKey =
'/' + objectName();
580 const QString setgrp = mSettingGroup.isEmpty() ? window()->objectName() : mSettingGroup;
591 if ( !isEnabled() || ( !mSaveCollapsedState && !mSaveCheckedState ) )
598 setUpdatesEnabled(
false );
600 if ( mSaveCheckedState )
602 const QVariant val = mSettings->value( key +
"/checked" );
604 setChecked( val.toBool() );
606 if ( mSaveCollapsedState )
608 const QVariant val = mSettings->value( key +
"/collapsed" );
613 setUpdatesEnabled(
true );
621 if ( !
mShown || !isEnabled() || ( !mSaveCollapsedState && !mSaveCheckedState ) )
628 if ( mSaveCheckedState )
629 mSettings->setValue( key + u
"/checked"_s, isChecked() );
630 if ( mSaveCollapsedState )
631 mSettings->setValue( key + u
"/collapsed"_s,
isCollapsed() );
637 mAltDown = (
event->modifiers() & ( Qt::AltModifier | Qt::ControlModifier ) );
638 mShiftDown = (
event->modifiers() & Qt::ShiftModifier );
639 QToolButton::mouseReleaseEvent( event );
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
QString syncGroup
An optional group to be collapsed and uncollapsed in sync with this group box if the Alt-modifier is ...
void changeEvent(QEvent *event) override
void collapseExpandFixes()
Visual fixes for when group box is collapsed/expanded.
QgsCollapsibleGroupBoxBasic(QWidget *parent=nullptr)
void setSyncGroup(const QString &grp)
Named group which synchronizes collapsing action when triangle is clicked while holding alt modifier ...
void checkToggled(bool ckd)
bool isCollapsed() const
Returns the current collapsed state of this group box.
void showEvent(QShowEvent *event) override
void collapsedStateChanged(bool collapsed)
Signal emitted when groupbox collapsed/expanded state is changed, and when first shown.
void checkClicked(bool ckd)
QgsGroupBoxCollapseButton * mCollapseButton
void setStyleSheet(const QString &style)
Overridden to prepare base call and avoid crash due to specific QT versions.
void setCollapsed(bool collapse)
Collapse or uncollapse this groupbox.
QScrollArea * mParentScrollArea
void mousePressEvent(QMouseEvent *event) override
void mouseReleaseEvent(QMouseEvent *event) override
void saveState() const
Will save the collapsed and checked state.
QgsCollapsibleGroupBox(QWidget *parent=nullptr, QgsSettings *settings=nullptr)
void showEvent(QShowEvent *event) override
void loadState()
Will load the collapsed and checked state.
~QgsCollapsibleGroupBox() override
void setSettings(QgsSettings *settings)
Stores settings for use within QGIS.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
const QString COLLAPSE_HIDE_BORDER_FIX
#define QgsDebugMsgLevel(str, level)