BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
ColumnResizer.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // BornAgain: simulate and fit reflection and scattering
4 //
5 //! @file GUI/coregui/Views/CommonWidgets/ColumnResizer.cpp
6 //! @brief Implements class ColumnResizer
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2018
11 //! @authors Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 /*
16  * Copyright 2011 Aurélien Gâteau <agateau@kde.org>
17  * License: LGPL v2.1 or later (see COPYING)
18  */
20 #include "Base/Utils/Assert.h"
21 
22 #include <QDebug>
23 #include <QEvent>
24 #include <QFormLayout>
25 #include <QGridLayout>
26 #include <QTimer>
27 #include <QWidget>
28 
29 class FormLayoutWidgetItem : public QWidgetItem {
30 public:
31  FormLayoutWidgetItem(QWidget* widget, QFormLayout* formLayout, QFormLayout::ItemRole itemRole)
32  : QWidgetItem(widget), m_width(-1), m_formLayout(formLayout), m_itemRole(itemRole)
33  {
34  }
35 
36  QSize sizeHint() const
37  {
38  QSize size = QWidgetItem::sizeHint();
39  if (m_width != -1) {
40  size.setWidth(m_width);
41  }
42  return size;
43  }
44 
45  QSize minimumSize() const
46  {
47  QSize size = QWidgetItem::minimumSize();
48  if (m_width != -1) {
49  size.setWidth(m_width);
50  }
51  return size;
52  }
53 
54  QSize maximumSize() const
55  {
56  QSize size = QWidgetItem::maximumSize();
57  if (m_width != -1) {
58  size.setWidth(m_width);
59  }
60  return size;
61  }
62 
63  void setWidth(int width)
64  {
65  if (width != m_width) {
66  m_width = width;
67  invalidate();
68  }
69  }
70 
71  void setGeometry(const QRect& _rect)
72  {
73  QRect rect = _rect;
74  int width = widget()->sizeHint().width();
75  if (m_itemRole == QFormLayout::LabelRole
76  && m_formLayout->labelAlignment() & Qt::AlignRight) {
77  rect.setLeft(rect.right() - width);
78  }
79  QWidgetItem::setGeometry(rect);
80  }
81 
82  QFormLayout* formLayout() const { return m_formLayout; }
83 
84 private:
85  int m_width;
86  QFormLayout* m_formLayout;
87  QFormLayout::ItemRole m_itemRole;
88 };
89 
90 typedef QPair<QGridLayout*, int> GridColumnInfo;
91 
93 public:
95  : q(q_ptr), m_updateTimer(new QTimer(q)), block_update(false)
96  {
97  m_updateTimer->setSingleShot(true);
98  m_updateTimer->setInterval(0);
99  QObject::connect(m_updateTimer, &QTimer::timeout, q, &ColumnResizer::updateWidth);
100  }
101 
103  {
104  if (block_update)
105  return;
106  m_updateTimer->start();
107  }
108 
110  QTimer* m_updateTimer;
111  QList<QWidget*> m_widgets;
112  QList<FormLayoutWidgetItem*> m_wrWidgetItemList;
113  QList<GridColumnInfo> m_gridColumnInfoList;
115 };
116 
117 ColumnResizer::ColumnResizer(QObject* parent) : QObject(parent), d(new ColumnResizerPrivate(this))
118 {
119 }
120 
122 {
123  delete d;
124 }
125 
126 void ColumnResizer::addWidget(QWidget* widget)
127 {
128  d->m_widgets.append(widget);
129  widget->installEventFilter(this);
131 }
132 
134 {
135  if (d->block_update)
136  return;
137  int width = 0;
138  for (auto widget : d->m_widgets) {
139  width = qMax(widget->sizeHint().width(), width);
140  }
141  for (auto item : d->m_wrWidgetItemList) {
142  item->setWidth(width);
143  item->formLayout()->update();
144  }
145  for (auto info : d->m_gridColumnInfoList) {
146  info.first->setColumnMinimumWidth(info.second, width);
147  }
148 }
149 
150 void ColumnResizer::removeWidget(QWidget* widget)
151 {
152  if (d->m_widgets.contains(widget)) {
153  d->m_widgets.removeAll(widget);
154  widget->removeEventFilter(this);
155  }
156 }
157 
158 bool ColumnResizer::eventFilter(QObject*, QEvent* event)
159 {
160  if (event->type() == QEvent::Resize) {
162  }
163  return false;
164 }
165 
166 void ColumnResizer::addWidgetsFromLayout(QLayout* layout, int column)
167 {
168  ASSERT(column >= 0);
169  QGridLayout* gridLayout = qobject_cast<QGridLayout*>(layout);
170  QFormLayout* formLayout = qobject_cast<QFormLayout*>(layout);
171  if (gridLayout) {
172  addWidgetsFromGridLayout(gridLayout, column);
173  } else if (formLayout) {
174  if (column > QFormLayout::SpanningRole) {
175  qCritical() << "column should not be more than" << QFormLayout::SpanningRole
176  << "for QFormLayout";
177  return;
178  }
179  QFormLayout::ItemRole role = static_cast<QFormLayout::ItemRole>(column);
180  addWidgetsFromFormLayout(formLayout, role);
181  } else {
182  qCritical() << "Don't know how to handle layout" << layout;
183  }
184 }
185 
186 void ColumnResizer::addWidgetsFromGridLayout(QGridLayout* layout, int column)
187 {
188  for (int row = 0; row < layout->rowCount(); ++row) {
189  QLayoutItem* item = layout->itemAtPosition(row, column);
190  if (!item) {
191  continue;
192  }
193  QWidget* widget = item->widget();
194  if (!widget) {
195  continue;
196  }
197  addWidget(widget);
198  }
199  d->m_gridColumnInfoList << GridColumnInfo(layout, column);
200 }
201 
202 void ColumnResizer::addWidgetsFromFormLayout(QFormLayout* layout, QFormLayout::ItemRole role)
203 {
204  for (int row = 0; row < layout->rowCount(); ++row) {
205  QLayoutItem* item = layout->itemAt(row, role);
206  if (!item) {
207  continue;
208  }
209  QWidget* widget = item->widget();
210  if (!widget) {
211  continue;
212  }
213  layout->removeItem(item);
214  delete item;
215  FormLayoutWidgetItem* newItem = new FormLayoutWidgetItem(widget, layout, role);
216  layout->setItem(row, role, newItem);
217  addWidget(widget);
218  d->m_wrWidgetItemList << newItem;
219  }
220 }
221 
223 {
224  // d->block_update = true;
225  // removing all widgets from being supervised
226  for (int row = 0; row < layout->rowCount(); ++row) {
227  for (int column = 0; column < layout->columnCount(); ++column) {
228  QLayoutItem* item = layout->itemAtPosition(row, column);
229  if (!item) {
230  continue;
231  }
232  QWidget* widget = item->widget();
233  if (!widget) {
234  continue;
235  }
236  removeWidget(widget);
237  }
238  }
239 
240  // removing their layout
241  QMutableListIterator<GridColumnInfo> it(d->m_gridColumnInfoList);
242  while (it.hasNext()) {
243  GridColumnInfo ci = it.next();
244  if (ci.first == layout) {
245  it.remove();
246  }
247  }
248 
249  // d->block_update = false;
250  // d->scheduleWidthUpdate();
251 }
252 
253 // void ColumnResizer::onObjectDestroyed(QObject *object)
254 //{
255 // qDebug() << "================================";
256 // qDebug() << "ColumnResizer::onObjectDestroyed" << object;
257 // d->block_update = true;
258 // if(QWidget *widget = dynamic_cast<QWidget *>(object)) {
259 // ASSERT(0);
260 // if(d->m_widgets.contains(widget)) {
261 // d->m_widgets.removeAll(widget);
262 // }
263 // }
264 // else if(QGridLayout *layout = qobject_cast<QGridLayout *>(object)) {
265 // QMutableListIterator<GridColumnInfo> it(d->m_gridColumnInfoList);
266 // while (it.hasNext()) {
267 // GridColumnInfo ci = it.next();
268 // if(ci.first == layout) {
269 // it.remove();
270 // }
271 // }
272 // }
273 // d->block_update = false;
274 //}
275 
276 // vi: ts=4 sw=4 et
Defines the macro ASSERT.
#define ASSERT(condition)
Definition: Assert.h:31
QPair< QGridLayout *, int > GridColumnInfo
Defines class ColumnResizer.
ColumnResizerPrivate(ColumnResizer *q_ptr)
QList< GridColumnInfo > m_gridColumnInfoList
QList< QWidget * > m_widgets
QList< FormLayoutWidgetItem * > m_wrWidgetItemList
The ColumnResizer class provides vertically aligned widgets from diferent layouts.
Definition: ColumnResizer.h:37
void removeWidget(QWidget *widget)
virtual bool eventFilter(QObject *, QEvent *event)
ColumnResizer(QObject *parent=0)
virtual ~ColumnResizer()
ColumnResizerPrivate *const d
Definition: ColumnResizer.h:58
void addWidget(QWidget *widget)
void addWidgetsFromGridLayout(QGridLayout *, int column)
void addWidgetsFromFormLayout(QFormLayout *, QFormLayout::ItemRole role)
void dropWidgetsFromGridLayout(QGridLayout *layout)
void addWidgetsFromLayout(QLayout *, int column)
FormLayoutWidgetItem(QWidget *widget, QFormLayout *formLayout, QFormLayout::ItemRole itemRole)
QSize sizeHint() const
QFormLayout::ItemRole m_itemRole
QFormLayout * m_formLayout
void setGeometry(const QRect &_rect)
QFormLayout * formLayout() const
QSize maximumSize() const
QSize minimumSize() const
void setWidth(int width)