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 )
149 QGroupBox::mousePressEvent( event );
154 mAltDown = (
event->modifiers() & ( Qt::AltModifier | Qt::ControlModifier ) );
155 mShiftDown = (
event->modifiers() & Qt::ShiftModifier );
168 QGroupBox::mouseReleaseEvent( event );
177 QGroupBox::changeEvent( event );
179 if ( event->type() == QEvent::EnabledChange && isEnabled() )
187 if ( !grp.isEmpty() )
189 tipTxt = tr(
"Ctrl (or Alt)-click to toggle all" ) +
'\n' + tr(
"Shift-click to expand, then collapse others" );
196 QStyleOptionGroupBox box;
197 initStyleOption( &box );
198 return style()->subControlRect( QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxLabel,
this );
243 if (
auto *lParentWidget = parentWidget() )
249 if (
mSyncParent->parentWidget()->objectName() !=
"QgisApp"_L1 )
268 if ( grpbox->syncGroup() ==
syncGroup() && grpbox->isEnabled() )
277 grpbox->setCollapsed(
mShiftDown ?
true : !thisCollapsed );
306 QGroupBox::setStyleSheet( style );
311 setUpdatesEnabled(
false );
315 QStyleOptionGroupBox box;
316 initStyleOption( &box );
317 const QRect rectFrame = style()->subControlRect( QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxFrame,
this );
321 const int marginLeft = 20;
322 const int marginRight = 5;
324 const int offsetStyle = QApplication::style()->objectName().contains(
"macintosh"_L1 ) ? 8 : 0;
325 const int topBuffer = 1 + offsetStyle;
326 int offsetTop = topBuffer;
327 int offsetTopTri = topBuffer;
331 offsetTopTri += ( rectTitle.height() -
mCollapseButton->height() ) / 2;
341 if ( QApplication::style()->objectName().compare(
"oxygen"_L1, Qt::CaseInsensitive ) == 0 )
343 QStyleOptionGroupBox box;
344 initStyleOption( &box );
345 const QRect rectFrame = style()->subControlRect( QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxFrame,
this );
346 const QRect rectCheckBox = style()->subControlRect( QStyle::CC_GroupBox, &box, QStyle::SC_GroupBoxCheckBox,
this );
347 if ( rectFrame.left() <= 0 )
348 offsetLeft = 6 + rectFrame.left();
349 if ( rectFrame.top() <= 0 )
354 offsetTop = ( rectCheckBox.height() / 2 ) - (
mCollapseButton->height() / 2 ) + rectCheckBox.top();
355 offsetTopTri = offsetTop + 1;
359 offsetTop = 6 + rectFrame.top();
360 offsetTopTri = offsetTop;
365 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 );
369 if ( QApplication::style()->objectName().contains(
"macintosh"_L1 ) )
371 ss +=
"QgsCollapsibleGroupBoxBasic, QgsCollapsibleGroupBox {"_L1;
372 ss += u
" margin-top: %1px;"_s.arg( topBuffer + rectFrame.top() );
375 ss +=
"QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::title {"_L1;
376 ss +=
" subcontrol-origin: margin;"_L1;
377 ss +=
" subcontrol-position: top left;"_L1;
378 ss += u
" margin-left: %1px;"_s.arg( marginLeft );
379 ss += u
" margin-right: %1px;"_s.arg( marginRight );
380 ss += u
" left: %1px;"_s.arg( offsetLeft );
381 ss += u
" top: %1px;"_s.arg( offsetTop );
382 if ( QApplication::style()->objectName().contains(
"macintosh"_L1 ) )
384 ss +=
" background-color: rgba(0,0,0,0)"_L1;
391 ssd = u
"QgsCollapsibleGroupBoxBasic > QToolButton#%1, QgsCollapsibleGroupBox > QToolButton#%1 {"_s.arg(
mCollapseButton->objectName() );
392 ssd +=
" background-color: rgba(255, 255, 255, 0); border: none;"_L1;
393 ssd += u
"} QgsCollapsibleGroupBoxBasic > QToolButton#%1:focus, QgsCollapsibleGroupBox > QToolButton#%1:focus { border: 1px solid palette(highlight); }"_s.arg(
mCollapseButton->objectName() );
395 if ( offsetLeft != 0 || offsetTopTri != 0 )
397 setUpdatesEnabled(
true );
423 setMaximumHeight( collapse ?
titleRect().bottom() + 6 : 16777215 );
430 QApplication::processEvents();
446 const char *hideKey =
"CollGrpBxHide";
448 QString ss = styleSheet();
457 const auto constChildren = children();
458 for ( QObject *child : constChildren )
460 QWidget *w = qobject_cast<QWidget *>( child );
465 w->setProperty( hideKey,
true );
478 const auto constChildren = children();
479 for ( QObject *child : constChildren )
481 QWidget *w = qobject_cast<QWidget *>( child );
484 if ( w->property( hideKey ).toBool() )
496 , mSettings( settings )
503 , mSettings( settings )
520 mSettings = settings;
521 mDelSettings =
false;
524void QgsCollapsibleGroupBox::init()
528 mDelSettings =
false;
535 mSaveCollapsedState =
true;
538 mSaveCheckedState =
false;
570 if ( objectName().isEmpty() || ( mSettingGroup.isEmpty() && window()->objectName().isEmpty() ) )
575 QString
saveKey =
'/' + objectName();
584 const QString setgrp = mSettingGroup.isEmpty() ? window()->objectName() : mSettingGroup;
595 if ( !isEnabled() || ( !mSaveCollapsedState && !mSaveCheckedState ) )
602 setUpdatesEnabled(
false );
604 if ( mSaveCheckedState )
606 const QVariant val = mSettings->value( key +
"/checked" );
608 setChecked( val.toBool() );
610 if ( mSaveCollapsedState )
612 const QVariant val = mSettings->value( key +
"/collapsed" );
617 setUpdatesEnabled(
true );
625 if ( !
mShown || !isEnabled() || ( !mSaveCollapsedState && !mSaveCheckedState ) )
632 if ( mSaveCheckedState )
633 mSettings->setValue( key + u
"/checked"_s, isChecked() );
634 if ( mSaveCollapsedState )
635 mSettings->setValue( key + u
"/collapsed"_s,
isCollapsed() );
641 mAltDown = (
event->modifiers() & ( Qt::AltModifier | Qt::ControlModifier ) );
642 mShiftDown = (
event->modifiers() & Qt::ShiftModifier );
643 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)