QGIS API Documentation 3.28.0-Firenze (ed3ad0430f)
qgspanelwidgetstack.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgspanelwidget.cpp
3 ---------------------
4 begin : June 2016
5 copyright : (C) 2016 by Nathan Woodrow
6 email :
7 ***************************************************************************
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 ***************************************************************************/
15#include <QDialogButtonBox>
16#include <QPushButton>
17#include <QDialog>
18#include <QSettings>
19
20#include "qgslogger.h"
21
22#include "qgspanelwidgetstack.h"
23
24#include "qgspanelwidget.h"
25
27 : QWidget( parent )
28{
29 setupUi( this );
30 clear();
31
32 connect( mBackButton, &QAbstractButton::clicked, this, &QgsPanelWidgetStack::acceptCurrentPanel );
33
34 mMenuButton->setStyleSheet( QStringLiteral( "QToolButton::menu-indicator { image: none; }" ) );
35}
36
38{
39 // TODO Don't allow adding another main widget or else that would be strange for the user.
41 // using unique connection because addMainPanel() may be called multiple times
42 // for a panel, so showPanel() slot could be invoked more times from one signal
43 Qt::UniqueConnection );
44 mStackedWidget->insertWidget( 0, panel );
45 mStackedWidget->setCurrentIndex( 0 );
46 updateMenuButton();
47}
48
50{
51 return qobject_cast<QgsPanelWidget *>( mStackedWidget->widget( 0 ) );
52}
53
55{
56 // clear out the current stack
58
59 QWidget *widget = mStackedWidget->widget( 0 );
60 if ( widget )
61 {
62 mStackedWidget->removeWidget( widget );
63 return qobject_cast<QgsPanelWidget *>( widget );
64 }
65 else
66 {
67 return nullptr;
68 }
69}
70
72{
73 for ( int i = mStackedWidget->count() - 1; i >= 0; i-- )
74 {
75 if ( QgsPanelWidget *panelWidget = qobject_cast<QgsPanelWidget *>( mStackedWidget->widget( i ) ) )
76 {
77 mStackedWidget->removeWidget( panelWidget );
78 if ( panelWidget->autoDelete() )
79 {
80 panelWidget->deleteLater();
81 }
82 }
83 else if ( QWidget *widget = mStackedWidget->widget( i ) )
84 {
85 mStackedWidget->removeWidget( widget );
86 widget->deleteLater();
87 }
88 }
89 mTitles.clear();
90 mTitleText->hide();
91 mBackButton->hide();
92 mMenuButton->hide();
93 this->updateBreadcrumb();
94}
95
97{
98 return qobject_cast<QgsPanelWidget *>( mStackedWidget->currentWidget() );
99}
100
102{
103 if ( const QgsPanelWidget *widget = qobject_cast<const QgsPanelWidget *>( mStackedWidget->currentWidget() ) )
104 {
105 if ( widget->applySizeConstraintsToStack() )
106 return widget->sizeHint();
107 }
108 return QWidget::sizeHint();
109}
110
112{
113 if ( const QgsPanelWidget *widget = qobject_cast<const QgsPanelWidget *>( mStackedWidget->currentWidget() ) )
114 {
115 if ( widget->applySizeConstraintsToStack() )
116 return widget->minimumSizeHint();
117 }
118
119 return QWidget::minimumSizeHint();
120}
121
123{
124 // You can't accept the main panel.
125 if ( mStackedWidget->currentIndex() <= 0 )
126 return;
127
128 QgsPanelWidget *widget = currentPanel();
129 widget->acceptPanel();
130}
131
133{
134 //avoid messy multiple redraws
135 setUpdatesEnabled( false );
136 mStackedWidget->setUpdatesEnabled( false );
137
138 for ( int i = mStackedWidget->count() - 1; i > 0; --i )
139 {
140 if ( QgsPanelWidget *panelWidget = qobject_cast<QgsPanelWidget *>( mStackedWidget->widget( i ) ) )
141 {
142 panelWidget->acceptPanel();
143 }
144 }
145 setUpdatesEnabled( true );
146 mStackedWidget->setUpdatesEnabled( true );
147}
148
150{
151 mTitles.push( panel->panelTitle() );
152
155
156 const int index = mStackedWidget->addWidget( panel );
157 mStackedWidget->setCurrentIndex( index );
158 mBackButton->show();
159 mTitleText->show();
160
161 updateMenuButton();
162 updateBreadcrumb();
163}
164
166{
167 mTitles.pop();
168 mStackedWidget->setCurrentIndex( mStackedWidget->currentIndex() - 1 );
169 mStackedWidget->removeWidget( panel );
170 if ( panel->autoDelete() )
171 {
172 panel->deleteLater();
173 }
174
175 if ( mStackedWidget->currentIndex() == 0 )
176 {
177 mBackButton->hide();
178 mTitleText->hide();
179 mMenuButton->hide();
180 }
181 else
182 {
183 updateMenuButton();
184 }
185 this->updateBreadcrumb();
186}
187
189{
190 if ( e->button() == Qt::BackButton )
191 {
193 }
194}
195
197{
198 if ( e->key() == Qt::Key_Escape )
199 {
201 }
202}
203
204void QgsPanelWidgetStack::updateBreadcrumb()
205{
206 QString breadcrumb;
207 const auto constMTitles = mTitles;
208 for ( const QString &title : constMTitles )
209 {
210 breadcrumb += QStringLiteral( " %1 >" ).arg( title );
211 }
212 // Remove the last
213 breadcrumb.chop( 1 );
214 mTitleText->setText( breadcrumb );
215}
216
217void QgsPanelWidgetStack::updateMenuButton()
218{
219 if ( QMenu *menu = currentPanel()->menuButtonMenu() )
220 {
221 mMenuButton->setVisible( true );
222 mMenuButton->setToolTip( currentPanel()->menuButtonTooltip() );
223 mMenuButton->setMenu( menu );
224 }
225 else
226 {
227 mMenuButton->setVisible( false );
228 }
229}
QgsPanelWidget * currentPanel()
Returns the panel currently shown in the stack.
void closePanel(QgsPanelWidget *panel)
Closes the panel in the widget.
QSize sizeHint() const override
void acceptAllPanels()
Accepts all panel widgets open in the stack in turn until only the mainPanel() remains.
QgsPanelWidgetStack(QWidget *parent=nullptr)
A stack widget to manage panels in the interface.
QgsPanelWidget * mainPanel()
The main panel widget that is set in the stack.
QSize minimumSizeHint() const override
void showPanel(QgsPanelWidget *panel)
Show a panel in the stack widget.
void acceptCurrentPanel()
Accept the current active widget in the stack.
void setMainPanel(QgsPanelWidget *panel SIP_TRANSFER)
Sets the main panel widget for the stack and selects it for the user.
QgsPanelWidget * takeMainPanel() SIP_TRANSFERBACK
Removes the main panel widget from the stack and transfers ownsership to the caller.
void clear()
Clear the stack of all widgets.
void mouseReleaseEvent(QMouseEvent *e) override
void keyPressEvent(QKeyEvent *e) override
Base class for any widget that can be shown as a inline panel.
void showPanel(QgsPanelWidget *panel)
Emit when you require a panel to be show in the interface.
QString panelTitle()
The title of the panel.
void panelAccepted(QgsPanelWidget *panel)
Emitted when the panel is accepted by the user.
bool autoDelete()
The the auto delete property on the widget.
void acceptPanel()
Accept the panel.