Fraxinus  18.10
An IGT application
cxDataViewSelectionWidget.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
12 #include "cxToolListWidget.h"
13 #include "cxData.h"
14 #include <QListWidgetItem>
15 #include <QDir>
16 #include <QHBoxLayout>
17 #include <QDropEvent>
18 #include <QMimeData>
19 #include <QAction>
20 #include <QLabel>
21 #include <QMenu>
22 #include "cxEnumConverter.h"
23 #include "cxLogger.h"
24 #include "cxImageAlgorithms.h"
25 #include "cxImage.h"
26 #include "cxPatientModelService.h"
27 #include "cxViewService.h"
28 #include "cxViewGroupData.h"
29 #include "cxLogger.h"
30 #include "cxActiveData.h"
31 
32 namespace cx
33 {
34 
35 DataListWidget::DataListWidget(PatientModelServicePtr patientModelService, QWidget* parent) :
36  QListWidget(parent),
37  mPatientModelService(patientModelService)
38 {
39 // connect(this, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(toolClickedSlot(QListWidgetItem*)));
40 
41  this->setSelectionBehavior(QAbstractItemView::SelectItems);
42  this->setSelectionMode(QAbstractItemView::SingleSelection);
43 
44  connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChangedSlot()));
45 
46 // this->setMinimumSize(QSize(20, 20));
47  this->setSizePolicy(QSizePolicy::Expanding, this->sizePolicy().verticalPolicy());
48 
49 }
50 
58 {
59  return QSize(80,20);
60 }
61 
62 //QSize DataListWidget::minimumSizeHint () const
63 //{
64 // return QSize(20,20);
65 //}
66 
68 {}
69 
70 void DataListWidget::populate(QStringList dataUids)
71 {
72  this->clear();
73 
74  foreach(QString data, dataUids)
75  {
76  this->populateData(data);
77  }
78  emit listSizeChanged();
79 }
80 
81 void DataListWidget::itemSelectionChangedSlot()
82 {
83  QList<QListWidgetItem*> items = this->selectedItems();
84  if (items.empty())
85  return;
86  DataPtr data = mPatientModelService->getData(items[0]->data(Qt::UserRole).toString());
87  if (data)
88  {
89  ActiveDataPtr activeData = mPatientModelService->getActiveData();
90  activeData->setActive(data);
91  }
92 }
93 
94 void DataListWidget::populateData(QString uid, bool indent, QListWidgetItem* after)
95 {
96  DataPtr data = mPatientModelService->getData(uid);
97  if (!data)
98  return;
99 
100  QListWidgetItem* item = new QListWidgetItem(data->getName());
101  item->setData(Qt::UserRole, uid);
102 
103  if (indent)
104  item->setText(" " + item->text());
105 
106  item->setIcon(data->getIcon());
107 
108  if (after)
109  {
110  std::cout << "set " << item->text() << " before: " << after->text() << " " << this->currentRow() << std::endl;
111  this->setCurrentItem(after);
112  this->insertItem(this->currentRow(), item);
113  this->setCurrentItem(item);
114  }
115  else
116  {
117  this->addItem(item);
118  }
119 
120  item->setToolTip(item->text());
121 
122  emit listSizeChanged();
123 }
124 
125 //---------------------------------------------------------------------------------------------------------------------
126 //---------------------------------------------------------------------------------------------------------------------
127 //---------------------------------------------------------------------------------------------------------------------
128 
129 
130 AllDataListWidget::AllDataListWidget(PatientModelServicePtr patientModelService, QWidget* parent) :
131  DataListWidget(patientModelService, parent)
132 {
133  this->setDropIndicatorShown(false);
134  this->setDragEnabled(true);
135 
136  connect(mPatientModelService.get(), SIGNAL(dataAddedOrRemoved()), this, SLOT(populateAllDataList()));
137  this->populateAllDataList();
138 }
139 
141 {}
142 
143 void AllDataListWidget::mousePressEvent(QMouseEvent *event)
144 {
145  QListWidget::mousePressEvent(event);
146 }
147 
148 void AllDataListWidget::mouseMoveEvent(QMouseEvent *event)
149 {
150  QListWidget::mouseMoveEvent(event);
151 }
152 
153 void AllDataListWidget::populateAllDataList()
154 {
155  this->clear();
156 
157  //add actions to the actiongroups and the contextmenu
158  std::vector<DataPtr> sorted = sortOnGroupsAndAcquisitionTime(mPatientModelService->getDatas());
159  QString lastDataActionUid = "________________________";
160  for (std::vector<DataPtr>::iterator iter=sorted.begin(); iter!=sorted.end(); ++iter)
161  {
162  QString uid = (*iter)->getUid();
163 
164  if (uid.contains(lastDataActionUid))
165  {
166  this->populateData(uid, true);
167  }
168  else
169  {
170  this->populateData(uid, false);
171  lastDataActionUid = uid;
172  }
173 
174  }
175 
176  emit listSizeChanged();
177 }
178 
179 
180 //---------------------------------------------------------------------------------------------------------------------
181 //---------------------------------------------------------------------------------------------------------------------
182 //---------------------------------------------------------------------------------------------------------------------
183 
184 
185 
187  DataListWidget(patientModelService, parent)
188 {
189  this->setContextMenuPolicy(Qt::CustomContextMenu);
190 
191  this->setDropIndicatorShown(true);
192  this->setDragEnabled(true);
193  this->setAcceptDrops(true);
194  this->viewport()->setAcceptDrops(true);
195  this->setDragDropOverwriteMode(true);
196 
197  connect(this, SIGNAL(userChangedList()), this, SLOT(userChangedListSlot()));
198  connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(contextMenuSlot(const QPoint &)));
199 }
200 
201 
203 {}
204 
205 
206 
208 {
209  QStringList data = this->getData();
210  std::reverse(data.begin(), data.end());
211 
212  mViewGroupData->clearData();
213  for (int i=0; i<data.size(); ++i)
214  {
215  DataPtr current = mPatientModelService->getData(data[i]);
216  if (!current)
217  continue;
218  mViewGroupData->addData(current->getUid());
219  }
220 }
221 
222 void SelectedDataListWidget::keyPressEvent(QKeyEvent* event)
223 {
224  if (event->matches(QKeySequence::Delete) || event->matches(QKeySequence::Back))
225  {
226  QList<QListWidgetItem*> items = this->selectedItems();
227  for (int i=0; i<items.size(); ++i)
228  delete items[i];
229  emit userChangedList();
230  emit listSizeChanged();
231  }
232 }
233 
238 QMap<int, QVariant> SelectedDataListWidget::convertFromCustomQtMimeFormat(const QMimeData* mimeData) const
239 {
240  QMap<int, QVariant> v;
241  if (!mimeData->hasFormat("application/x-qabstractitemmodeldatalist"))
242  return v;
243 
244  QByteArray itemData = mimeData->data("application/x-qabstractitemmodeldatalist");
245  QDataStream stream(&itemData, QIODevice::ReadOnly);
246  int r, c;
247 // QMap<int, QVariant> v;
248  stream >> r >> c >> v;
249 // std::cout << "var: " << r << " " << c << " " << v.size() << std::endl;
250 // if (!v.empty())
251 // {
252 // QString uid = v[Qt::UserRole].toString();
253 // std::cout << "v: " << " " << v.begin()->typeName() << " " << v.begin()->toString() << " uid= " << uid << std::endl;
254 //
257 // }
258  return v;
259 }
260 
261 void SelectedDataListWidget::dropEvent(QDropEvent *event)
262 {
263  if (event->source()==this)
264  {
265  std::cout << "drop this: " << event->mimeData()->formats().join(",") << std::endl;
266  event->setDropAction(Qt::MoveAction);
267  }
268 
269  QString sourceUid;
270  QMap<int, QVariant> sourceData = this->convertFromCustomQtMimeFormat(event->mimeData());
271  if (sourceData.contains(Qt::UserRole))
272  sourceUid = sourceData[Qt::UserRole].toString();
273 
274 // if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
275 // {
276 // QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
277 // QDataStream stream(&itemData, QIODevice::ReadOnly);
278 // int r, c;
279 // QMap<int, QVariant> v;
280 // stream >> r >> c >> v;
281 // std::cout << "var: " << r << " " << c << " " << v.size() << std::endl;
282 // if (!v.empty())
283 // {
284 // QString uid = v[Qt::UserRole].toString();
285 // std::cout << "v: " << " " << v.begin()->typeName() << " " << v.begin()->toString() << " uid= " << uid << std::endl;
286 //
288 // newUid = uid;
289 // }
290 // }
291 
292  QListWidgetItem* itemToDelete = 0;
293  for(int i=0; i < this->count(); ++i)
294  {
295  QListWidgetItem* item = this->item(i);
296  if (item->data(Qt::UserRole)==sourceUid)
297  itemToDelete = item;
298  }
299 
300 // std:: cout << "received dropEvent: " << event->mimeData()->text() << std::endl;
301 // this->populateData(event->mimeData()->text(), false, pos);
302 // event->setDropAction(Qt::MoveAction);
303 // event->accept();
304 // std::cout << "dropaction " << event->dropAction() << std::endl;
305  QListWidget::dropEvent(event);
306  if (event->source()!=this) // remove old item if new if moved in from external source
307  delete itemToDelete;
308 
309  emit userChangedList();
310  emit listSizeChanged();
311 }
312 
314 {
315  QStringList retval;
316 
317  for(int i=0; i < this->count(); ++i)
318  {
319  QListWidgetItem* item = this->item(i);
320  retval << item->data(Qt::UserRole).toString();
321  }
322 
323  return retval;
324 }
325 
326 void SelectedDataListWidget::deleteSlot()
327 {
328  if(!mItemToDelete)
329  {
330  reportDebug("Found no item to delete...");
331  return;
332  }
333  this->deleteItemSlot(mItemToDelete);
334 }
335 
336 void SelectedDataListWidget::deleteItemSlot(QListWidgetItem* item)
337 {
338  delete item;
339  emit userChangedList();
340  emit listSizeChanged();
341 }
342 
343 void SelectedDataListWidget::contextMenuSlot(const QPoint& point)
344 {
345  QWidget* sender = dynamic_cast<QWidget*>(this->sender());
346  QPoint pointGlobal = sender->mapToGlobal(point);
347  QMenu contextMenu(sender);
348 
349  QAction* action = new QAction("Remove", &contextMenu);
350 
351  QListWidgetItem* item = this->itemAt(point);
352  if(!item)
353  {
354  reportDebug("Found no item to delete...");
355  }
356  mItemToDelete = item;
357 
358  connect(action, SIGNAL(triggered()), this, SLOT(deleteSlot()));
359  contextMenu.addAction(action);
360 
361  contextMenu.exec(pointGlobal);
362 }
363 
365 {
366  this->clear();
367 
368  std::vector<DataPtr> sorted = mViewGroupData->getData();
369  std::reverse(sorted.begin(), sorted.end());
370  for (std::vector<DataPtr>::iterator iter=sorted.begin(); iter!=sorted.end(); ++iter)
371  {
372  QString uid = (*iter)->getUid();
373  this->populateData(uid);
374  }
375 
376  emit listSizeChanged();
377 }
378 
380 {
381  if (mViewGroupData)
382  {
383  disconnect(mViewGroupData.get(), &ViewGroupData::initialized, this, &SelectedDataListWidget::populateList);
384  disconnect(mViewGroupData.get(), &ViewGroupData::dataViewPropertiesChanged, this, &SelectedDataListWidget::populateList);
385  }
386 
387  mViewGroupData = viewGroupData;
388 
389  if (mViewGroupData)
390  {
391  connect(mViewGroupData.get(), &ViewGroupData::initialized, this, &SelectedDataListWidget::populateList);
393  }
394 
395  this->populateList();
396 }
397 
398 
399 
400 //---------------------------------------------------------
401 //---------------------------------------------------------
402 //---------------------------------------------------------
403 
404 
405 class AbraClass : public QListWidget
406 {
407 public:
408  AbraClass(QWidget* parent) : QListWidget(parent) {}
409 protected:
410  void dropEvent(QDropEvent *event)
411  {
412 // QListWidgetItem* pos = NULL;
413 
414  if (event->source()==this)
415  {
416  std::cout << "drop this: " << event->mimeData()->formats().join(",") << std::endl;
417  event->setDropAction(Qt::MoveAction);
418  }
419 
420  QString newUid;
421  if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
422  {
423  QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
424  QDataStream stream(&itemData, QIODevice::ReadOnly);
425  int r, c;
426  QMap<int, QVariant> v;
427  stream >> r >> c >> v;
428  std::cout << "var: " << r << " " << c << " " << v.size() << std::endl;
429  if (!v.empty())
430  {
431  std::cout << "v: " << " " << v.begin()->typeName() << " " << v.begin()->toString() << std::endl;
432  newUid = v.begin()->toString();
433  }
434  }
435 
436  QListWidgetItem* itemToDelete = 0;
437  for(int i=0; i < this->count(); ++i)
438  {
439  QListWidgetItem* item = this->item(i);
440  if (item->text()==newUid)
441  itemToDelete = item;
442  }
443 
444  // std:: cout << "received dropEvent: " << event->mimeData()->text() << std::endl;
445 // this->populateData(event->mimeData()->text(), false, pos);
446 // event->setDropAction(Qt::MoveAction);
447 // event->accept();
448  std::cout << "dropaction " << event->dropAction() << std::endl;
449  QListWidget::dropEvent(event);
450  if (event->source()!=this) // remove old item if new if moved in from external source
451  delete itemToDelete;
452  }
453 
454 };
455 
456 class TestClass : public QListWidget
457 {
458 public:
459  TestClass(QWidget* parent) : QListWidget(parent) {}
460 protected:
461  void dropEvent(QDropEvent *event)
462  {
463  // ignore drop
464  event->setDropAction(Qt::MoveAction);
465  event->acceptProposedAction();
466 // QListWidget::dropEvent(event);
467  }
468 
469 };
470 
472  mViewService(viewService)
473 {
474  // TODO Auto-generated constructor stub
475  QHBoxLayout* layout = new QHBoxLayout(this);
476 
477  mSelectedDataListWidget = new SelectedDataListWidget(patientModelService, this);
478  mAllDataListWidget = new AllDataListWidget(patientModelService, this);
479 #if 0
480  TestClass* test = new TestClass(this);
481  test->addItem("test1");
482  test->addItem("test2");
483  test->addItem("test3");
484  test->addItem("test4");
485  //test->setDragDropMode(QAbstractItemView::InternalMove);
486  test->setDropIndicatorShown(false);
487  test->setDragEnabled(true);
488  test->setAcceptDrops(true);
489 
490  AbraClass* abra = new AbraClass(this);
491  abra->addItem("abra1");
492  abra->addItem("abra2");
493  abra->addItem("abra3");
494  abra->addItem("abra4");
495 // abra->setDragDropMode(QAbstractItemView::InternalMove);
496  abra->setDropIndicatorShown(true);
497  abra->setDragEnabled(true);
498  abra->setAcceptDrops(true);
499  abra->viewport()->setAcceptDrops(true);
500  abra->setDragDropOverwriteMode(true);
501 
502  layout->addWidget(test);
503  layout->addWidget(abra);
504 #endif
505 
506  QVBoxLayout* selLayout = new QVBoxLayout;
507  mVisibleLabel = new QLabel("Visible", this);
508  selLayout->addWidget(mVisibleLabel);
509  selLayout->addWidget(mSelectedDataListWidget);
510  layout->addLayout(selLayout);
511 
512  QVBoxLayout* allLayout = new QVBoxLayout;
513  allLayout->addWidget(new QLabel("All"));
514  allLayout->addWidget(mAllDataListWidget);
515  layout->addLayout(allLayout);
516 
517  connect(mViewService.get(), SIGNAL(activeViewChanged()), this, SLOT(viewGroupChangedSlot()));
518  this->viewGroupChangedSlot();
519 }
520 
521 void DataViewSelectionWidget::viewGroupChangedSlot()
522 {
523  int vg = mViewService->getActiveGroupId();
524  if (vg<0)
525  vg = 0;
526 
527  ViewGroupDataPtr group = mViewService->getGroup(vg);
528  if (group)
529  mSelectedDataListWidget->setViewGroupData(group);
530 
531  mVisibleLabel->setText("Visible in group "+qstring_cast(vg));
532 }
533 
534 
536 {
537  // TODO Auto-generated destructor stub
538 }
539 
540 }
QString qstring_cast(const T &val)
boost::shared_ptr< class ViewGroupData > ViewGroupDataPtr
Definition: cxViewGroup.h:29
void setViewGroupData(ViewGroupDataPtr viewGroupData)
std::string toString(T const &value)
converts any type to a string
Definition: catch.hpp:755
void mouseMoveEvent(QMouseEvent *event)
void mousePressEvent(QMouseEvent *event)
virtual QSize sizeHint() const
SelectedDataListWidget(PatientModelServicePtr patientModelService, QWidget *parent=NULL)
boost::shared_ptr< class ActiveData > ActiveDataPtr
Definition: cxColorWidget.h:21
boost::shared_ptr< class ViewService > ViewServicePtr
TestClass(QWidget *parent)
void listSizeChanged()
emitted whenever the count changes
virtual void dropEvent(QDropEvent *event)
void userChangedList()
emitted whenever the user changes the list
void populateData(QString uid, bool indent=false, QListWidgetItem *after=NULL)
boost::shared_ptr< class Data > DataPtr
QMap< int, QVariant > convertFromCustomQtMimeFormat(const QMimeData *mimeData) const
std::vector< T > sortOnGroupsAndAcquisitionTime(std::map< QString, T > input)
void populate(QStringList dataUids)
QStringList getData()
get absolute file path to all tools currently in the list
AbraClass(QWidget *parent)
boost::shared_ptr< class PatientModelService > PatientModelServicePtr
DataViewSelectionWidget(PatientModelServicePtr patientModelService, ViewServicePtr viewService, QWidget *parent=NULL)
void dropEvent(QDropEvent *event)
void dropEvent(QDropEvent *event)
void dataViewPropertiesChanged(QString uid)
AllDataListWidget(PatientModelServicePtr patientModelService, QWidget *parent=NULL)
DataListWidget(PatientModelServicePtr patientModelService, QWidget *parent=NULL)
PatientModelServicePtr mPatientModelService
void reportDebug(QString msg)
Definition: cxLogger.cpp:68
Namespace for all CustusX production code.