22
22
23
23
#include < QToolButton>
24
24
#include < QMouseEvent>
25
+ #include < QPushButton>
25
26
#include < QStyleOptionGroupBox>
26
27
#include < QSettings>
27
28
#include < QScrollArea>
@@ -47,7 +48,6 @@ QgsCollapsibleGroupBoxBasic::~QgsCollapsibleGroupBoxBasic()
47
48
// QgsDebugMsg( "Entered" );
48
49
}
49
50
50
-
51
51
void QgsCollapsibleGroupBoxBasic::init ()
52
52
{
53
53
// QgsDebugMsg( "Entered" );
@@ -126,6 +126,10 @@ void QgsCollapsibleGroupBoxBasic::showEvent( QShowEvent * event )
126
126
// emit signal for connections using collapsed state
127
127
emit collapsedStateChanged ( isCollapsed () );
128
128
}
129
+
130
+ // verify triangle mirrors groupbox's enabled state
131
+ mCollapseButton ->setEnabled ( isEnabled () );
132
+
129
133
// set mShown after first setCollapsed call or expanded groupboxes
130
134
// will scroll scroll areas when first shown
131
135
mShown = true ;
@@ -149,7 +153,7 @@ void QgsCollapsibleGroupBoxBasic::mousePressEvent( QMouseEvent *event )
149
153
150
154
void QgsCollapsibleGroupBoxBasic::mouseReleaseEvent ( QMouseEvent *event )
151
155
{
152
- mAltDown = ( event->modifiers () & Qt::AltModifier );
156
+ mAltDown = ( event->modifiers () & ( Qt::AltModifier | Qt::ControlModifier ) );
153
157
mTitleClicked = ( titleRect ().contains ( event->pos () ) );
154
158
155
159
// sync group when title is alt-clicked
@@ -177,6 +181,19 @@ void QgsCollapsibleGroupBoxBasic::changeEvent( QEvent *event )
177
181
mCollapseButton ->setEnabled ( true );
178
182
}
179
183
184
+ void QgsCollapsibleGroupBoxBasic::setSyncGroup ( QString grp )
185
+ {
186
+ mSyncGroup = grp;
187
+ if ( !grp.isEmpty () )
188
+ {
189
+ mCollapseButton ->setToolTip ( tr ( " Ctrl(or Alt)-click to toggle all" ) );
190
+ }
191
+ else
192
+ {
193
+ mCollapseButton ->setToolTip ( QString ( " " ) );
194
+ }
195
+ }
196
+
180
197
QRect QgsCollapsibleGroupBoxBasic::titleRect () const
181
198
{
182
199
QStyleOptionGroupBox box;
@@ -255,20 +272,34 @@ void QgsCollapsibleGroupBoxBasic::updateStyle()
255
272
{
256
273
setUpdatesEnabled ( false );
257
274
275
+ QSettings settings;
276
+ // NOTE: QGIS-Style groupbox styled in app stylesheet
277
+ bool usingQgsStyle = settings.value ( " qgis/stylesheet/groupBoxCustom" , QVariant ( false ) ).toBool ();
278
+
279
+ QStyleOptionGroupBox box;
280
+ initStyleOption ( &box );
281
+ QRect rectFrame = style ()->subControlRect ( QStyle::CC_GroupBox, &box,
282
+ QStyle::SC_GroupBoxFrame, this );
283
+ QRect rectTitle = titleRect ();
284
+
258
285
// margin/offset defaults
259
286
int marginLeft = 20 ; // title margin for disclosure triangle
260
287
int marginRight = 5 ; // a little bit of space on the right, to match space on the left
261
288
int offsetLeft = 0 ; // offset for oxygen theme
262
- int offsetTop = 0 ;
263
- // int offsetTop2 = 0; // offset for triangle
264
-
265
- // starting top offset for custom groupboxes in app stylesheet
266
- QStyleOptionGroupBox box;
267
- initStyleOption ( &box );
268
- QRect rectCheckBox = style ()->subControlRect ( QStyle::CC_GroupBox, &box,
269
- QStyle::SC_GroupBoxCheckBox, this );
270
- int offsetTop2 = rectCheckBox.top (); // offset for triangle
289
+ int offsetStyle = QApplication::style ()->objectName ().contains ( " macintosh" ) ? 1 : 0 ;
290
+ int topBuffer = ( usingQgsStyle ? 3 : 1 ) + offsetStyle; // space between top of title or triangle and widget above
291
+ int offsetTop = topBuffer;
292
+ int offsetTopTri = topBuffer; // offset for triangle
271
293
294
+ if ( mCollapseButton ->height () < rectTitle.height () ) // triangle's height > title text's, offset triangle
295
+ {
296
+ offsetTopTri += ( rectTitle.height () - mCollapseButton ->height () ) / 2 ;
297
+ // offsetTopTri += rectTitle.top();
298
+ }
299
+ else if ( rectTitle.height () < mCollapseButton ->height () ) // title text's height < triangle's, offset title
300
+ {
301
+ offsetTop += ( mCollapseButton ->height () - rectTitle.height () ) / 2 ;
302
+ }
272
303
273
304
// calculate offset if frame overlaps triangle (oxygen theme)
274
305
// using an offset of 6 pixels from frame border
@@ -289,22 +320,27 @@ void QgsCollapsibleGroupBoxBasic::updateStyle()
289
320
// if is checkable align with checkbox
290
321
offsetTop = ( rectCheckBox.height () / 2 ) -
291
322
( mCollapseButton ->height () / 2 ) + rectCheckBox.top ();
292
- offsetTop2 = offsetTop + 1 ;
323
+ offsetTopTri = offsetTop + 1 ;
293
324
}
294
325
else
295
326
{
296
327
offsetTop = 6 + rectFrame.top ();
297
- offsetTop2 = offsetTop;
328
+ offsetTopTri = offsetTop;
298
329
}
299
330
}
300
331
}
301
332
302
333
QgsDebugMsg ( QString ( " groupbox: %1 style: %2 offset: left=%3 top=%4 top2=%5" ).arg (
303
- objectName () ).arg ( QApplication::style ()->objectName () ).arg ( offsetLeft ).arg ( offsetTop ).arg ( offsetTop2 ) );
334
+ objectName () ).arg ( QApplication::style ()->objectName () ).arg ( offsetLeft ).arg ( offsetTop ).arg ( offsetTopTri ) );
304
335
305
336
// customize style sheet for collapse/expand button and force left-aligned title
306
- // TODO: move to app stylesheet system, when appropriate
307
337
QString ss;
338
+ if ( usingQgsStyle || QApplication::style ()->objectName ().contains ( " macintosh" ) )
339
+ {
340
+ ss += " QgsCollapsibleGroupBoxBasic, QgsCollapsibleGroupBox {" ;
341
+ ss += QString ( " margin-top: %1px;" ).arg ( topBuffer + ( usingQgsStyle ? rectTitle.height () + 5 : rectFrame.top () ) );
342
+ ss += " }" ;
343
+ }
308
344
ss += " QgsCollapsibleGroupBoxBasic::title, QgsCollapsibleGroupBox::title {" ;
309
345
ss += " subcontrol-origin: margin;" ;
310
346
ss += " subcontrol-position: top left;" ;
@@ -321,8 +357,8 @@ void QgsCollapsibleGroupBoxBasic::updateStyle()
321
357
ssd += " background-color: rgba(255, 255, 255, 0); border: none;" ;
322
358
ssd += " }" ;
323
359
mCollapseButton ->setStyleSheet ( ssd );
324
- if ( offsetLeft != 0 || offsetTop2 != 0 )
325
- mCollapseButton ->move ( offsetLeft, offsetTop2 );
360
+ if ( offsetLeft != 0 || offsetTopTri != 0 )
361
+ mCollapseButton ->move ( offsetLeft, offsetTopTri );
326
362
327
363
setUpdatesEnabled ( true );
328
364
}
@@ -341,6 +377,31 @@ void QgsCollapsibleGroupBoxBasic::setCollapsed( bool collapse )
341
377
// avoid flicker in X11
342
378
QApplication::processEvents ();
343
379
380
+ // handle QPushButtons in form layouts that stay visible on collapse (Qt bug)
381
+ // set flat on collapse for fix, but preserve button's flat value when expanding
382
+ if ( collapse )
383
+ {
384
+ foreach ( QPushButton* pBtn, findChildren<QPushButton *>() )
385
+ {
386
+ if ( ! pBtn->isFlat () )
387
+ {
388
+ if ( ! pBtn->property ( " PushButtonFlat" ).isValid () )
389
+ pBtn->setProperty ( " PushButtonFlat" , QVariant ( false ) );
390
+
391
+ pBtn->setFlat ( true );
392
+ }
393
+ }
394
+ }
395
+ else
396
+ {
397
+ foreach ( QPushButton* pBtn, findChildren<QPushButton *>() )
398
+ {
399
+ // restore any previous flat value
400
+ if ( pBtn->property ( " PushButtonFlat" ).isValid () )
401
+ pBtn->setFlat ( false );
402
+ }
403
+ }
404
+
344
405
// set maximum height to hide contents - does this work in all envs?
345
406
// setMaximumHeight( collapse ? 25 : 16777215 );
346
407
setMaximumHeight ( collapse ? titleRect ().bottom () + 6 : 16777215 );
0 commit comments