MIRA
SelectionListDialog.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 by
3  * MetraLabs GmbH (MLAB), GERMANY
4  * and
5  * Neuroinformatics and Cognitive Robotics Labs (NICR) at TU Ilmenau, GERMANY
6  * All rights reserved.
7  *
8  * Contact: info@mira-project.org
9  *
10  * Commercial Usage:
11  * Licensees holding valid commercial licenses may use this file in
12  * accordance with the commercial license agreement provided with the
13  * software or, alternatively, in accordance with the terms contained in
14  * a written agreement between you and MLAB or NICR.
15  *
16  * GNU General Public License Usage:
17  * Alternatively, this file may be used under the terms of the GNU
18  * General Public License version 3.0 as published by the Free Software
19  * Foundation and appearing in the file LICENSE.GPL3 included in the
20  * packaging of this file. Please review the following information to
21  * ensure the GNU General Public License version 3.0 requirements will be
22  * met: http://www.gnu.org/copyleft/gpl.html.
23  * Alternatively you may (at your option) use any later version of the GNU
24  * General Public License if such license has been publicly approved by
25  * MLAB and NICR (or its successors, if any).
26  *
27  * IN NO EVENT SHALL "MLAB" OR "NICR" BE LIABLE TO ANY PARTY FOR DIRECT,
28  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF
29  * THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF "MLAB" OR
30  * "NICR" HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * "MLAB" AND "NICR" SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
33  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
34  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
35  * ON AN "AS IS" BASIS, AND "MLAB" AND "NICR" HAVE NO OBLIGATION TO
36  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS.
37  */
38 
49 #include <QDialog>
50 #include <QDialogButtonBox>
51 #include <QVBoxLayout>
52 #include <QMessageBox>
53 #include <QTreeWidget>
54 
55 #include <map>
56 #include <list>
57 #include <set>
58 
59 #include <utils/Foreach.h>
60 
61 #include <widgets/TreeViewFilter.h>
62 
63 #ifndef _MIRA_SELECTIONLISTDIALOG_H_
64 #define _MIRA_SELECTIONLISTDIALOG_H_
65 
66 namespace mira {
67 
69 
113 template <typename T>
114 class SelectionListDialog : public QDialog
115 {
116 public:
117 
118  SelectionListDialog(QWidget* parent=0);
119 
120 public:
121 
127  void setHeaderLabels(const QStringList& labels);
128 
136  void addItem(const QStringList& labels, T data=T(), bool selected=false);
137 
145  void addItem(const QString& category, const QStringList& labels, T data=T(),
146  bool selected=false);
147 
148 
149 public:
150 
151  virtual void accept();
152 
159  void setSelectOnlyOneItemPerCategory(bool onlyOne);
160 
161  // Enables or disables multiple item selection, by default it is disabled.
162  void setMultiSelection(bool enable);
163 
170  std::list<std::pair<QString, T>> selectedItems() const;
171 
172 protected:
173 
174  QTreeWidgetItem* addCategory(const QString& category);
175 
176 protected:
177 
179 
180 protected:
181 
182  QDialogButtonBox* mButtonBox;
183  QTreeWidget* mTreeWidget;
185 
186  std::map<QString, QTreeWidgetItem*> mCategories;
187  std::map<const QTreeWidgetItem*, T> mItems;
188 
189 };
190 
192 
193 template <typename T>
195  QDialog(parent),
196  mOnlyOnePerCategory(false)
197 {
198  this->resize(640,480);
199 
200  QVBoxLayout *mainLayout = new QVBoxLayout;
201  //mainLayout->setSizeConstraint(QLayout::SetFixedSize);
202 
203  mTreeWidget = new QTreeWidget(this);
204  mTreeWidget->setRootIsDecorated(false);
205  mTreeWidget->setAlternatingRowColors(true);
206 
207 
208  TreeViewFilter* filter = new TreeViewFilter(mTreeWidget, this);
209  filter->setExpandAll(true);
210  filter->setFocus();
211 
212  mainLayout->addWidget(filter);
213 
214  mainLayout->addWidget(mTreeWidget);
215 
216  mAdditionalContentLayout = new QVBoxLayout;
217  mainLayout->addLayout(mAdditionalContentLayout);
218 
219  mButtonBox = new QDialogButtonBox(QDialogButtonBox::Ok |
220  QDialogButtonBox::Cancel);
221 
222  connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
223  connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
224  connect(mTreeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(accept()));
225  mainLayout->addWidget(mButtonBox);
226  setLayout(mainLayout);
227 
228 }
229 
230 template <typename T>
231 inline void SelectionListDialog<T>::setHeaderLabels(const QStringList& labels)
232 {
233  mTreeWidget->setHeaderLabels(labels);
234 }
235 
236 template <typename T>
237 inline QTreeWidgetItem* SelectionListDialog<T>::addCategory(const QString& category)
238 {
239  QTreeWidgetItem* item;
240 
241  item = new QTreeWidgetItem(mTreeWidget, QStringList(category));
242  mTreeWidget->addTopLevelItem(item);
243  QFont font = item->font(0);
244  font.setBold(true);
245  item->setFont(0,font);
246  item->setFlags(Qt::ItemIsEnabled);
247  item->setExpanded(true);
248  mCategories[category] = item;
249  mTreeWidget->resizeColumnToContents(0);
250  return item;
251 }
252 
253 template <typename T>
254 inline void SelectionListDialog<T>::addItem(const QString& category,
255  const QStringList& labels, T data,
256  bool selected)
257 {
258  assert(!category.isEmpty());
259 
260  QTreeWidgetItem* parent = NULL;
261  auto it = mCategories.find(category);
262  if(it != mCategories.end())
263  parent = it->second;
264  else {
265  parent = addCategory(category);
266  mCategories.insert(std::make_pair(category, parent));
267  }
268  assert(parent!=NULL);
269 
270  QTreeWidgetItem* item = new QTreeWidgetItem(parent, labels);
271  parent->addChild(item);
272  item->setSelected(selected);
273  mItems.insert(std::make_pair(item,data));
274  mTreeWidget->resizeColumnToContents(0);
275 }
276 
277 template <typename T>
278 inline void SelectionListDialog<T>::addItem(const QStringList& labels, T data,
279  bool selected)
280 {
281  QTreeWidgetItem* item = new QTreeWidgetItem(labels);
282  mTreeWidget->addTopLevelItem(item);
283  item->setSelected(selected);
284  mItems.insert(std::make_pair(item,data));
285  mTreeWidget->resizeColumnToContents(0);
286 }
287 
288 template <typename T>
290 {
291  std::set<QString> itemsPerCategory;
292  // check users selection
293  if (mOnlyOnePerCategory)
294  {
295  foreach(const QTreeWidgetItem* i, mTreeWidget->selectedItems()) {
296  auto it = mItems.find(i);
297  if(it==mItems.end() || i->parent()==NULL)
298  continue; // skip
299  if (itemsPerCategory.count(i->parent()->text(0)) > 0)
300  {
301  QMessageBox::critical(this, "Multiple items selected",
302  "You have selected more than one item per category");
303  return;
304  }
305  itemsPerCategory.insert(i->parent()->text(0));
306  }
307  }
308  QDialog::accept();
309 }
310 
311 template <typename T>
313 {
314  mOnlyOnePerCategory = onlyOne;
315 }
316 
317 template <typename T>
319 {
320  mTreeWidget->setSelectionMode(enable ? QAbstractItemView::MultiSelection :
321  QAbstractItemView::SingleSelection);
322 }
323 
324 template <typename T>
325 inline std::list<std::pair<QString, T>> SelectionListDialog<T>::selectedItems() const
326 {
327  std::list<std::pair<QString, T>> r;
328 
329  for(QTreeWidgetItemIterator i(mTreeWidget, QTreeWidgetItemIterator::Selected); *i; ++i)
330  {
331  auto it = mItems.find(*i);
332  if(it==mItems.end())
333  continue; // skip
334 
335  r.push_back(std::make_pair((*i)->text(0), it->second));
336  }
337  return r;
338 }
339 
341 
342 }
343 
344 #endif
Macro for iterating over all elements in a container.
std::map< const QTreeWidgetItem *, T > mItems
Definition: SelectionListDialog.h:187
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
QTreeWidgetItem * addCategory(const QString &category)
Definition: SelectionListDialog.h:237
void setExpandAll(bool expandAll)
If set to true, all (visible) nodes in the tree will be always expanded.
std::list< std::pair< QString, T > > selectedItems() const
Returns a list containing the selected items as pairs of strings and the data that was assigned in ad...
Definition: SelectionListDialog.h:325
QVBoxLayout * mAdditionalContentLayout
Definition: SelectionListDialog.h:178
A dialog for providing the a list, where the items can be grouped in categories.
Definition: SelectionListDialog.h:114
void setHeaderLabels(const QStringList &labels)
Sets the labels of the columns.
Definition: SelectionListDialog.h:231
Filter widget containing an line edit that filters the elements of an assigned TreeView.
bool mOnlyOnePerCategory
Definition: SelectionListDialog.h:184
void setMultiSelection(bool enable)
Definition: SelectionListDialog.h:318
void addItem(const QStringList &labels, T data=T(), bool selected=false)
Adds a new item to the list.
Definition: SelectionListDialog.h:278
QTreeWidget * mTreeWidget
Definition: SelectionListDialog.h:183
virtual void accept()
Definition: SelectionListDialog.h:289
SelectionListDialog(QWidget *parent=0)
Definition: SelectionListDialog.h:194
std::map< QString, QTreeWidgetItem * > mCategories
Definition: SelectionListDialog.h:186
void setSelectOnlyOneItemPerCategory(bool onlyOne)
If set to true the user is allowed to only select one item per category.
Definition: SelectionListDialog.h:312
QDialogButtonBox * mButtonBox
Definition: SelectionListDialog.h:182
Definition: TreeViewFilter.h:64