Libkdepim

kwidgetlister.cpp
1 /* -*- c++ -*-
2 
3  kwidgetlister.cpp
4 
5  This file is part of libkdepim.
6  SPDX-FileCopyrightText: 2001 Marc Mutz <[email protected]>
7 
8  SPDX-License-Identifier: GPL-2.0-or-later
9 */
10 
11 #include "kwidgetlister.h"
12 
13 #include <KGuiItem>
14 #include <KLocalizedString>
15 #include <QHBoxLayout>
16 
17 #include <QPushButton>
18 #include <QVBoxLayout>
19 
20 #include <KStandardGuiItem>
21 #include <cassert>
22 
23 using namespace KPIM;
24 
25 class Q_DECL_HIDDEN KWidgetLister::KWidgetListerPrivate
26 {
27 public:
28  KWidgetListerPrivate(KWidgetLister *qq)
29  : q(qq)
30  {
31  }
32 
33  ~KWidgetListerPrivate()
34  {
35  qDeleteAll(mWidgetList);
36  mWidgetList.clear();
37  }
38 
39  void enableControls();
40 
41  KWidgetLister *q = nullptr;
42  QPushButton *mBtnMore = nullptr;
43  QPushButton *mBtnFewer = nullptr;
44  QPushButton *mBtnClear = nullptr;
45  QVBoxLayout *mLayout = nullptr;
46  QWidget *mButtonBox = nullptr;
47  QList<QWidget *> mWidgetList;
48  int mMinWidgets = 0;
49  int mMaxWidgets = 0;
50 };
51 
52 void KWidgetLister::KWidgetListerPrivate::enableControls()
53 {
54  const int count = mWidgetList.count();
55  const bool isMaxWidgets = (count >= mMaxWidgets);
56  const bool isMinWidgets = (count <= mMinWidgets);
57  if (mBtnMore) {
58  mBtnMore->setEnabled(!isMaxWidgets);
59  }
60  if (mBtnFewer) {
61  mBtnFewer->setEnabled(!isMinWidgets);
62  }
63 }
64 
65 KWidgetLister::KWidgetLister(bool fewerMoreButton, int minWidgets, int maxWidgets, QWidget *parent)
66  : QWidget(parent)
67  , d(new KWidgetListerPrivate(this))
68 {
69  d->mMinWidgets = qMax(minWidgets, 1);
70  d->mMaxWidgets = qMax(maxWidgets, d->mMinWidgets + 1);
71  init(fewerMoreButton);
72 }
73 
75 
76 void KWidgetLister::init(bool fewerMoreButton)
77 {
78  //--------- the button box
79  d->mLayout = new QVBoxLayout(this);
80  d->mLayout->setContentsMargins({});
81  d->mLayout->setSpacing(4);
82  d->mLayout->setAlignment(Qt::AlignTop);
83 
84  d->mButtonBox = new QWidget(this);
85  auto mButtonBoxHBoxLayout = new QHBoxLayout(d->mButtonBox);
86  mButtonBoxHBoxLayout->setContentsMargins({});
87  d->mLayout->addWidget(d->mButtonBox);
88 
89  if (fewerMoreButton) {
90  d->mBtnMore = new QPushButton(d->mButtonBox);
91  mButtonBoxHBoxLayout->addWidget(d->mBtnMore);
92  KGuiItem::assign(d->mBtnMore, KGuiItem(i18nc("more widgets", "More"), QStringLiteral("list-add")));
93  mButtonBoxHBoxLayout->setStretchFactor(d->mBtnMore, 0);
94 
95  d->mBtnFewer = new QPushButton(d->mButtonBox);
96  mButtonBoxHBoxLayout->addWidget(d->mBtnFewer);
97  KGuiItem::assign(d->mBtnFewer, KGuiItem(i18nc("fewer widgets", "Fewer"), QStringLiteral("list-remove")));
98  mButtonBoxHBoxLayout->setStretchFactor(d->mBtnFewer, 0);
99  }
100  auto spacer = new QWidget(d->mButtonBox);
101  mButtonBoxHBoxLayout->addWidget(spacer);
102  mButtonBoxHBoxLayout->setStretchFactor(spacer, 1);
103 
104  d->mBtnClear = new QPushButton(d->mButtonBox);
105  mButtonBoxHBoxLayout->addWidget(d->mBtnClear);
106  KGuiItem::assign(d->mBtnClear, KStandardGuiItem::clear());
107  // FIXME a useful what's this. KStandardGuiItem::clear() returns a text with an edit box
108  d->mBtnClear->setWhatsThis(QString());
109  mButtonBoxHBoxLayout->setStretchFactor(d->mBtnClear, 0);
110 
111  //---------- connect everything
112  if (fewerMoreButton) {
114  connect(d->mBtnFewer, &QPushButton::clicked, this, &KWidgetLister::slotFewer);
115  }
116 
117  connect(d->mBtnClear, &QPushButton::clicked, this, &KWidgetLister::slotClear);
118 
119  d->enableControls();
120 }
121 
123 {
124  // the class should make certain that slotMore can't
125  // be called when mMaxWidgets are on screen.
126  assert(d->mWidgetList.count() < d->mMaxWidgets);
127 
128  addWidgetAtEnd();
129  // adjustSize();
130  d->enableControls();
131 }
132 
134 {
135  // the class should make certain that slotFewer can't
136  // be called when mMinWidgets are on screen.
137  assert(d->mWidgetList.count() > d->mMinWidgets);
138 
140  // adjustSize();
141  d->enableControls();
142 }
143 
145 {
146  setNumberOfShownWidgetsTo(d->mMinWidgets);
147 
148  // clear remaining widgets
149  for (QWidget *widget : std::as_const(d->mWidgetList)) {
150  clearWidget(widget);
151  }
152 
153  // adjustSize();
154  d->enableControls();
156 }
157 
159 {
160  if (!widget) {
161  widget = this->createWidget(this);
162  }
163 
164  d->mLayout->insertWidget(d->mLayout->indexOf(d->mButtonBox), widget);
165  d->mWidgetList.append(widget);
166  widget->show();
167 
168  d->enableControls();
170  Q_EMIT widgetAdded(widget);
171 }
172 
174 {
175  // The layout will take care that the
176  // widget is removed from screen, too.
177  delete d->mWidgetList.takeLast();
178  d->enableControls();
180 }
181 
183 {
184  Q_UNUSED(widget)
185 }
186 
188 {
189  return new QWidget(parent);
190 }
191 
193 {
194  int superfluousWidgets = qMax(d->mWidgetList.count() - aNum, 0);
195  int missingWidgets = qMax(aNum - d->mWidgetList.count(), 0);
196 
197  // remove superfluous widgets
198  for (; superfluousWidgets; superfluousWidgets--) {
200  }
201 
202  // add missing widgets
203  for (; missingWidgets; missingWidgets--) {
204  addWidgetAtEnd();
205  }
206 }
207 
209 {
210  return d->mWidgetList;
211 }
212 
214 {
215  return d->mMinWidgets;
216 }
217 
219 {
220  return d->mMaxWidgets;
221 }
222 
224 {
225  // The layout will take care that the
226  // widget is removed from screen, too.
227 
228  if (d->mWidgetList.count() <= widgetsMinimum()) {
229  return;
230  }
231 
232  const int index = d->mWidgetList.indexOf(widget);
233  QWidget *w = d->mWidgetList.takeAt(index);
234  w->deleteLater();
235  w = nullptr;
236  d->enableControls();
237  Q_EMIT widgetRemoved(widget);
239 }
240 
242 {
243  if (!widget) {
244  widget = this->createWidget(this);
245  }
246 
247  int index = d->mLayout->indexOf(currentWidget ? currentWidget : d->mButtonBox) + 1;
248  d->mLayout->insertWidget(index, widget);
249  if (currentWidget) {
250  index = d->mWidgetList.indexOf(currentWidget);
251  d->mWidgetList.insert(index + 1, widget);
252  } else {
253  d->mWidgetList.append(widget);
254  }
255  widget->show();
256 
257  d->enableControls();
259  Q_EMIT widgetAdded(widget);
260 }
261 
262 #include "moc_kwidgetlister.cpp"
AlignTop
QWidget(QWidget *parent, Qt::WindowFlags f)
~KWidgetLister() override
Destroys the widget lister.
virtual void addWidgetAtEnd(QWidget *widget=nullptr)
Adds a single widget.
Q_EMITQ_EMIT
int count(const T &value) const const
void clicked(bool checked)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QList< QWidget * > widgets() const
Returns the list of widgets.
void deleteLater()
static void assign(QPushButton *button, const KGuiItem &item)
KGuiItem clear()
virtual QWidget * createWidget(QWidget *parent)
Returns a new widget that shall be added to the lister.
Widget that manages a list of other widgets (incl.
Definition: kwidgetlister.h:40
void widgetRemoved()
This signal is emitted whenever a widget was removed.
virtual void removeLastWidget()
Removes a single (always the last) widget.
virtual void removeWidget(QWidget *widget)
Remove specific widget.
void show()
virtual void slotMore()
Called whenever the user clicks on the 'more' button.
virtual void clearWidget(QWidget *w)
Called to clear a given widget.
int widgetsMinimum() const
The minimum number of widgets that are to stay on screen.
KWidgetLister(bool fewerMoreButton, int minWidgets=1, int maxWidgets=8, QWidget *parent=nullptr)
Creates a new widget lister.
Class KCheckComboBox::KCheckComboBoxPrivate.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
virtual void slotFewer()
Called whenever the user clicks on the 'fewer' button.
void clearWidgets()
This signal is emitted whenever the clear button is clicked.
void widgetAdded()
This signal is emitted whenever a widget was added.
int widgetsMaximum() const
The maximum number of widgets that are to be shown on screen.
virtual void setNumberOfShownWidgetsTo(int count)
Sets the number of widgets on screen to exactly count.
QObject * parent() const const
virtual void addWidgetAfterThisWidget(QWidget *currentWidget, QWidget *widget=nullptr)
Add widget after specific widget.
virtual void slotClear()
Called whenever the user clicks on the 'clear' button.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Dec 5 2023 04:12:38 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.