27#include <QStyleOptionGroupBox>
40 : QGroupBox( title, parent )
73 setFocusPolicy( Qt::StrongFocus );
97 if ( parent() && parent()->parent() )
107 QgsDebugMsgLevel( QStringLiteral(
"did not find a QScrollArea parent" ), 5 );
135 if ( event->modifiers() & ( Qt::AltModifier | Qt::ControlModifier | Qt::ShiftModifier )
144 QGroupBox::mousePressEvent( event );
149 mAltDown = (
event->modifiers() & ( Qt::AltModifier | Qt::ControlModifier ) );
150 mShiftDown = (
event->modifiers() & Qt::ShiftModifier );
164 QGroupBox::mouseReleaseEvent( event );
173 QGroupBox::changeEvent( event );
175 if ( event->type() == QEvent::EnabledChange && isEnabled() )
183 if ( !grp.isEmpty() )
185 tipTxt = tr(
"Ctrl (or Alt)-click to toggle all" ) +
'\n' + tr(
"Shift-click to expand, then collapse others" );
192 QStyleOptionGroupBox box;
193 initStyleOption( &box );
194 return style()->subControlRect( QStyle::CC_GroupBox, &box,
195 QStyle::SC_GroupBoxLabel,
this );
238 QgsDebugMsg( QStringLiteral(
"Alt or Shift key down, syncing group" ) );
240 if (
auto *lParentWidget = parentWidget() )
246 if (
mSyncParent->parentWidget()->objectName() != QLatin1String(
"QgisApp" ) )
265 if ( grpbox->syncGroup() ==
syncGroup() && grpbox->isEnabled() )
274 grpbox->setCollapsed(
mShiftDown ?
true : !thisCollapsed );
284 QgsDebugMsg( QStringLiteral(
"did not find a sync parent" ) );
303 QGroupBox::setStyleSheet( style );
308 setUpdatesEnabled(
false );
312 QStyleOptionGroupBox box;
313 initStyleOption( &box );
314 const QRect rectFrame = style()->subControlRect( QStyle::CC_GroupBox, &box,
315 QStyle::SC_GroupBoxFrame,
this );
319 const int marginLeft = 20;
320 const int marginRight = 5;
322 const int offsetStyle = QApplication::style()->objectName().contains( QLatin1String(
"macintosh" ) ) ? 8 : 0;
323 const int topBuffer = 1 + offsetStyle;
324 int offsetTop = topBuffer;
325 int offsetTopTri = topBuffer;
329 offsetTopTri += ( rectTitle.height() -
mCollapseButton->height() ) / 2;
339 if ( QApplication::style()->objectName().compare( QLatin1String(
"oxygen" ), Qt::CaseInsensitive ) == 0 )
341 QStyleOptionGroupBox box;
342 initStyleOption( &box );
343 const QRect rectFrame = style()->subControlRect( QStyle::CC_GroupBox, &box,
344 QStyle::SC_GroupBoxFrame,
this );
345 const QRect rectCheckBox = style()->subControlRect( QStyle::CC_GroupBox, &box,
346 QStyle::SC_GroupBoxCheckBox,
this );
347 if ( rectFrame.left() <= 0 )
348 offsetLeft = 6 + rectFrame.left();
349 if ( rectFrame.top() <= 0 )
354 offsetTop = ( rectCheckBox.height() / 2 ) -
356 offsetTopTri = offsetTop + 1;
360 offsetTop = 6 + rectFrame.top();
361 offsetTopTri = offsetTop;
366 QgsDebugMsgLevel( QStringLiteral(
"groupbox: %1 style: %2 offset: left=%3 top=%4 top2=%5" ).arg(
367 objectName(), QApplication::style()->objectName() ).arg( offsetLeft ).arg( offsetTop ).arg( offsetTopTri ), 5 );
371 if ( QApplication::style()->objectName().contains( QLatin1String(
"macintosh" ) ) )
373 ss += QLatin1String(
"QgsCollapsibleGroupBoxBasic, QgsCollapsibleGroupBox {" );
374 ss += QStringLiteral(
" margin-top: %1px;" ).arg( topBuffer + rectFrame.top() );
377 ss += QLatin1String(
"QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::title {" );
378 ss += QLatin1String(
" subcontrol-origin: margin;" );
379 ss += QLatin1String(
" subcontrol-position: top left;" );
380 ss += QStringLiteral(
" margin-left: %1px;" ).arg( marginLeft );
381 ss += QStringLiteral(
" margin-right: %1px;" ).arg( marginRight );
382 ss += QStringLiteral(
" left: %1px;" ).arg( offsetLeft );
383 ss += QStringLiteral(
" top: %1px;" ).arg( offsetTop );
384 if ( QApplication::style()->objectName().contains( QLatin1String(
"macintosh" ) ) )
386 ss += QLatin1String(
" background-color: rgba(0,0,0,0)" );
393 ssd = QStringLiteral(
"QgsCollapsibleGroupBoxBasic > QToolButton#%1, QgsCollapsibleGroupBox > QToolButton#%1 {" ).arg(
mCollapseButton->objectName() );
394 ssd += QLatin1String(
" background-color: rgba(255, 255, 255, 0); border: none;" );
395 ssd += QStringLiteral(
"} QgsCollapsibleGroupBoxBasic > QToolButton#%1:focus, QgsCollapsibleGroupBox > QToolButton#%1:focus { border: 1px solid palette(highlight); }" ).arg(
mCollapseButton->objectName() );
397 if ( offsetLeft != 0 || offsetTopTri != 0 )
399 setUpdatesEnabled(
true );
425 setMaximumHeight( collapse ?
titleRect().bottom() + 6 : 16777215 );
432 QApplication::processEvents();
448 const char *hideKey =
"CollGrpBxHide";
450 QString ss = styleSheet();
459 const auto constChildren = children();
460 for ( QObject *child : constChildren )
462 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 )
504 , mSettings( settings )
568 if ( objectName().isEmpty() || (
mSettingGroup.isEmpty() && window()->objectName().isEmpty() ) )
573 QString
saveKey =
'/' + objectName();
600 setUpdatesEnabled(
false );
604 const QVariant val =
mSettings->value( key +
"/checked" );
606 setChecked( val.toBool() );
610 const QVariant val =
mSettings->value( key +
"/collapsed" );
615 setUpdatesEnabled(
true );
631 mSettings->setValue( key + QStringLiteral(
"/checked" ), isChecked() );
639 mAltDown = (
event->modifiers() & ( Qt::AltModifier | Qt::ControlModifier ) );
640 mShiftDown = (
event->modifiers() & Qt::ShiftModifier );
641 QToolButton::mouseReleaseEvent( event );
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
A groupbox that collapses/expands when toggled.
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.
QPointer< QgsSettings > mSettings
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)
This class is a composition of two QSettings instances:
static bool isNull(const QVariant &variant)
Returns true if the specified variant should be considered a NULL value.
const QString COLLAPSE_HIDE_BORDER_FIX
#define QgsDebugMsgLevel(str, level)