QGIS API Documentation  3.27.0-Master (e113457133)
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  mStackedWidget->removeWidget( widget );
61  return qobject_cast<QgsPanelWidget *>( widget );
62 }
63 
65 {
66  for ( int i = mStackedWidget->count() - 1; i >= 0; i-- )
67  {
68  if ( QgsPanelWidget *panelWidget = qobject_cast<QgsPanelWidget *>( mStackedWidget->widget( i ) ) )
69  {
70  mStackedWidget->removeWidget( panelWidget );
71  if ( panelWidget->autoDelete() )
72  {
73  panelWidget->deleteLater();
74  }
75  }
76  else if ( QWidget *widget = mStackedWidget->widget( i ) )
77  {
78  mStackedWidget->removeWidget( widget );
79  widget->deleteLater();
80  }
81  }
82  mTitles.clear();
83  mTitleText->hide();
84  mBackButton->hide();
85  mMenuButton->hide();
86  this->updateBreadcrumb();
87 }
88 
90 {
91  return qobject_cast<QgsPanelWidget *>( mStackedWidget->currentWidget() );
92 }
93 
95 {
96  if ( const QgsPanelWidget *widget = qobject_cast<const QgsPanelWidget *>( mStackedWidget->currentWidget() ) )
97  {
98  if ( widget->applySizeConstraintsToStack() )
99  return widget->sizeHint();
100  }
101  return QWidget::sizeHint();
102 }
103 
105 {
106  if ( const QgsPanelWidget *widget = qobject_cast<const QgsPanelWidget *>( mStackedWidget->currentWidget() ) )
107  {
108  if ( widget->applySizeConstraintsToStack() )
109  return widget->minimumSizeHint();
110  }
111 
112  return QWidget::minimumSizeHint();
113 }
114 
116 {
117  // You can't accept the main panel.
118  if ( mStackedWidget->currentIndex() <= 0 )
119  return;
120 
121  QgsPanelWidget *widget = currentPanel();
122  widget->acceptPanel();
123 }
124 
126 {
127  //avoid messy multiple redraws
128  setUpdatesEnabled( false );
129  mStackedWidget->setUpdatesEnabled( false );
130 
131  for ( int i = mStackedWidget->count() - 1; i > 0; --i )
132  {
133  if ( QgsPanelWidget *panelWidget = qobject_cast<QgsPanelWidget *>( mStackedWidget->widget( i ) ) )
134  {
135  panelWidget->acceptPanel();
136  }
137  }
138  setUpdatesEnabled( true );
139  mStackedWidget->setUpdatesEnabled( true );
140 }
141 
143 {
144  mTitles.push( panel->panelTitle() );
145 
148 
149  const int index = mStackedWidget->addWidget( panel );
150  mStackedWidget->setCurrentIndex( index );
151  mBackButton->show();
152  mTitleText->show();
153 
154  updateMenuButton();
155  updateBreadcrumb();
156 }
157 
159 {
160  mTitles.pop();
161  mStackedWidget->setCurrentIndex( mStackedWidget->currentIndex() - 1 );
162  mStackedWidget->removeWidget( panel );
163  if ( panel->autoDelete() )
164  {
165  panel->deleteLater();
166  }
167 
168  if ( mStackedWidget->currentIndex() == 0 )
169  {
170  mBackButton->hide();
171  mTitleText->hide();
172  mMenuButton->hide();
173  }
174  else
175  {
176  updateMenuButton();
177  }
178  this->updateBreadcrumb();
179 }
180 
182 {
183  if ( e->button() == Qt::BackButton )
184  {
186  }
187 }
188 
190 {
191  if ( e->key() == Qt::Key_Escape )
192  {
194  }
195 }
196 
197 void QgsPanelWidgetStack::updateBreadcrumb()
198 {
199  QString breadcrumb;
200  const auto constMTitles = mTitles;
201  for ( const QString &title : constMTitles )
202  {
203  breadcrumb += QStringLiteral( " %1 >" ).arg( title );
204  }
205  // Remove the last
206  breadcrumb.chop( 1 );
207  mTitleText->setText( breadcrumb );
208 }
209 
210 void QgsPanelWidgetStack::updateMenuButton()
211 {
212  if ( QMenu *menu = currentPanel()->menuButtonMenu() )
213  {
214  mMenuButton->setVisible( true );
215  mMenuButton->setToolTip( currentPanel()->menuButtonTooltip() );
216  mMenuButton->setMenu( menu );
217  }
218  else
219  {
220  mMenuButton->setVisible( false );
221  }
222 }
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.