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