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