Fraxinus  16.5.0-fx-rc1
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
33 #include "cxToolListWidget.h"
34 #include "cxData.h"
35 #include <QListWidgetItem>
36 #include <QDir>
37 #include <QHBoxLayout>
38 #include <QDropEvent>
39 #include <QMimeData>
40 #include <QAction>
41 #include <QLabel>
42 #include <QMenu>
43 #include "cxEnumConverter.h"
44 #include "cxLogger.h"
45 #include "cxImageAlgorithms.h"
46 #include "cxImage.h"
47 #include "cxPatientModelService.h"
48 #include "cxViewService.h"
49 #include "cxViewGroupData.h"
50 #include "cxLogger.h"
51 #include "cxActiveData.h"
52 
53 namespace cx
54 {
55 
56 DataListWidget::DataListWidget(PatientModelServicePtr patientModelService, QWidget* parent) :
57  QListWidget(parent),
58  mPatientModelService(patientModelService)
59 {
60 // connect(this, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(toolClickedSlot(QListWidgetItem*)));
61 
62  this->setSelectionBehavior(QAbstractItemView::SelectItems);
63  this->setSelectionMode(QAbstractItemView::SingleSelection);
64 
65  connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChangedSlot()));
66 
67 // this->setMinimumSize(QSize(20, 20));
68  this->setSizePolicy(QSizePolicy::Expanding, this->sizePolicy().verticalPolicy());
69 
70 }
71 
79 {
80  return QSize(80,20);
81 }
82 
83 //QSize DataListWidget::minimumSizeHint () const
84 //{
85 // return QSize(20,20);
86 //}
87 
89 {}
90 
91 void DataListWidget::populate(QStringList dataUids)
92 {
93  this->clear();
94 
95  foreach(QString data, dataUids)
96  {
97  this->populateData(data);
98  }
99  emit listSizeChanged();
100 }
101 
102 void DataListWidget::itemSelectionChangedSlot()
103 {
104  QList<QListWidgetItem*> items = this->selectedItems();
105  if (items.empty())
106  return;
107  DataPtr data = mPatientModelService->getData(items[0]->data(Qt::UserRole).toString());
108  if (data)
109  {
110  ActiveDataPtr activeData = mPatientModelService->getActiveData();
111  activeData->setActive(data);
112  }
113 }
114 
115 void DataListWidget::populateData(QString uid, bool indent, QListWidgetItem* after)
116 {
117  DataPtr data = mPatientModelService->getData(uid);
118  if (!data)
119  return;
120 
121  QListWidgetItem* item = new QListWidgetItem(data->getName());
122  item->setData(Qt::UserRole, uid);
123 
124  if (indent)
125  item->setText(" " + item->text());
126 
127  item->setIcon(data->getIcon());
128 
129  if (after)
130  {
131  std::cout << "set " << item->text() << " before: " << after->text() << " " << this->currentRow() << std::endl;
132  this->setCurrentItem(after);
133  this->insertItem(this->currentRow(), item);
134  this->setCurrentItem(item);
135  }
136  else
137  {
138  this->addItem(item);
139  }
140 
141  item->setToolTip(item->text());
142 
143  emit listSizeChanged();
144 }
145 
146 //---------------------------------------------------------------------------------------------------------------------
147 //---------------------------------------------------------------------------------------------------------------------
148 //---------------------------------------------------------------------------------------------------------------------
149 
150 
151 AllDataListWidget::AllDataListWidget(PatientModelServicePtr patientModelService, QWidget* parent) :
152  DataListWidget(patientModelService, parent)
153 {
154  this->setDropIndicatorShown(false);
155  this->setDragEnabled(true);
156 
157  connect(mPatientModelService.get(), SIGNAL(dataAddedOrRemoved()), this, SLOT(populateAllDataList()));
158  this->populateAllDataList();
159 }
160 
162 {}
163 
164 void AllDataListWidget::mousePressEvent(QMouseEvent *event)
165 {
166  QListWidget::mousePressEvent(event);
167 }
168 
169 void AllDataListWidget::mouseMoveEvent(QMouseEvent *event)
170 {
171  QListWidget::mouseMoveEvent(event);
172 }
173 
174 void AllDataListWidget::populateAllDataList()
175 {
176  this->clear();
177 
178  //add actions to the actiongroups and the contextmenu
179  std::vector<DataPtr> sorted = sortOnGroupsAndAcquisitionTime(mPatientModelService->getData());
180  QString lastDataActionUid = "________________________";
181  for (std::vector<DataPtr>::iterator iter=sorted.begin(); iter!=sorted.end(); ++iter)
182  {
183  QString uid = (*iter)->getUid();
184 
185  if (uid.contains(lastDataActionUid))
186  {
187  this->populateData(uid, true);
188  }
189  else
190  {
191  this->populateData(uid, false);
192  lastDataActionUid = uid;
193  }
194 
195  }
196 
197  emit listSizeChanged();
198 }
199 
200 
201 //---------------------------------------------------------------------------------------------------------------------
202 //---------------------------------------------------------------------------------------------------------------------
203 //---------------------------------------------------------------------------------------------------------------------
204 
205 
206 
208  DataListWidget(patientModelService, parent)
209 {
210  this->setContextMenuPolicy(Qt::CustomContextMenu);
211 
212  this->setDropIndicatorShown(true);
213  this->setDragEnabled(true);
214  this->setAcceptDrops(true);
215  this->viewport()->setAcceptDrops(true);
216  this->setDragDropOverwriteMode(true);
217 
218  connect(this, SIGNAL(userChangedList()), this, SLOT(userChangedListSlot()));
219  connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, SLOT(contextMenuSlot(const QPoint &)));
220 }
221 
222 
224 {}
225 
226 
227 
229 {
230  QStringList data = this->getData();
231  std::reverse(data.begin(), data.end());
232 
233  mViewGroupData->clearData();
234  for (int i=0; i<data.size(); ++i)
235  {
236  DataPtr current = mPatientModelService->getData(data[i]);
237  if (!current)
238  continue;
239  mViewGroupData->addData(current->getUid());
240  }
241 }
242 
243 void SelectedDataListWidget::keyPressEvent(QKeyEvent* event)
244 {
245  if (event->matches(QKeySequence::Delete) || event->matches(QKeySequence::Back))
246  {
247  QList<QListWidgetItem*> items = this->selectedItems();
248  for (int i=0; i<items.size(); ++i)
249  delete items[i];
250  emit userChangedList();
251  emit listSizeChanged();
252  }
253 }
254 
259 QMap<int, QVariant> SelectedDataListWidget::convertFromCustomQtMimeFormat(const QMimeData* mimeData) const
260 {
261  QMap<int, QVariant> v;
262  if (!mimeData->hasFormat("application/x-qabstractitemmodeldatalist"))
263  return v;
264 
265  QByteArray itemData = mimeData->data("application/x-qabstractitemmodeldatalist");
266  QDataStream stream(&itemData, QIODevice::ReadOnly);
267  int r, c;
268 // QMap<int, QVariant> v;
269  stream >> r >> c >> v;
270 // std::cout << "var: " << r << " " << c << " " << v.size() << std::endl;
271 // if (!v.empty())
272 // {
273 // QString uid = v[Qt::UserRole].toString();
274 // std::cout << "v: " << " " << v.begin()->typeName() << " " << v.begin()->toString() << " uid= " << uid << std::endl;
275 //
278 // }
279  return v;
280 }
281 
282 void SelectedDataListWidget::dropEvent(QDropEvent *event)
283 {
284  if (event->source()==this)
285  {
286  std::cout << "drop this: " << event->mimeData()->formats().join(",") << std::endl;
287  event->setDropAction(Qt::MoveAction);
288  }
289 
290  QString sourceUid;
291  QMap<int, QVariant> sourceData = this->convertFromCustomQtMimeFormat(event->mimeData());
292  if (sourceData.contains(Qt::UserRole))
293  sourceUid = sourceData[Qt::UserRole].toString();
294 
295 // if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
296 // {
297 // QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
298 // QDataStream stream(&itemData, QIODevice::ReadOnly);
299 // int r, c;
300 // QMap<int, QVariant> v;
301 // stream >> r >> c >> v;
302 // std::cout << "var: " << r << " " << c << " " << v.size() << std::endl;
303 // if (!v.empty())
304 // {
305 // QString uid = v[Qt::UserRole].toString();
306 // std::cout << "v: " << " " << v.begin()->typeName() << " " << v.begin()->toString() << " uid= " << uid << std::endl;
307 //
309 // newUid = uid;
310 // }
311 // }
312 
313  QListWidgetItem* itemToDelete = 0;
314  for(int i=0; i < this->count(); ++i)
315  {
316  QListWidgetItem* item = this->item(i);
317  if (item->data(Qt::UserRole)==sourceUid)
318  itemToDelete = item;
319  }
320 
321 // std:: cout << "received dropEvent: " << event->mimeData()->text() << std::endl;
322 // this->populateData(event->mimeData()->text(), false, pos);
323 // event->setDropAction(Qt::MoveAction);
324 // event->accept();
325 // std::cout << "dropaction " << event->dropAction() << std::endl;
326  QListWidget::dropEvent(event);
327  if (event->source()!=this) // remove old item if new if moved in from external source
328  delete itemToDelete;
329 
330  emit userChangedList();
331  emit listSizeChanged();
332 }
333 
335 {
336  QStringList retval;
337 
338  for(int i=0; i < this->count(); ++i)
339  {
340  QListWidgetItem* item = this->item(i);
341  retval << item->data(Qt::UserRole).toString();
342  }
343 
344  return retval;
345 }
346 
347 void SelectedDataListWidget::deleteSlot()
348 {
349  if(!mItemToDelete)
350  {
351  reportDebug("Found no item to delete...");
352  return;
353  }
354  this->deleteItemSlot(mItemToDelete);
355 }
356 
357 void SelectedDataListWidget::deleteItemSlot(QListWidgetItem* item)
358 {
359  delete item;
360  emit userChangedList();
361  emit listSizeChanged();
362 }
363 
364 void SelectedDataListWidget::contextMenuSlot(const QPoint& point)
365 {
366  QWidget* sender = dynamic_cast<QWidget*>(this->sender());
367  QPoint pointGlobal = sender->mapToGlobal(point);
368  QMenu contextMenu(sender);
369 
370  QAction* action = new QAction("Remove", &contextMenu);
371 
372  QListWidgetItem* item = this->itemAt(point);
373  if(!item)
374  {
375  reportDebug("Found no item to delete...");
376  }
377  mItemToDelete = item;
378 
379  connect(action, SIGNAL(triggered()), this, SLOT(deleteSlot()));
380  contextMenu.addAction(action);
381 
382  contextMenu.exec(pointGlobal);
383 }
384 
386 {
387  this->clear();
388 
389  std::vector<DataPtr> sorted = mViewGroupData->getData();
390  std::reverse(sorted.begin(), sorted.end());
391  for (std::vector<DataPtr>::iterator iter=sorted.begin(); iter!=sorted.end(); ++iter)
392  {
393  QString uid = (*iter)->getUid();
394  this->populateData(uid);
395  }
396 
397  emit listSizeChanged();
398 }
399 
401 {
402  if (mViewGroupData)
403  {
404  disconnect(mViewGroupData.get(), &ViewGroupData::initialized, this, &SelectedDataListWidget::populateList);
405  disconnect(mViewGroupData.get(), &ViewGroupData::dataViewPropertiesChanged, this, &SelectedDataListWidget::populateList);
406  }
407 
408  mViewGroupData = viewGroupData;
409 
410  if (mViewGroupData)
411  {
412  connect(mViewGroupData.get(), &ViewGroupData::initialized, this, &SelectedDataListWidget::populateList);
414  }
415 
416  this->populateList();
417 }
418 
419 
420 
421 //---------------------------------------------------------
422 //---------------------------------------------------------
423 //---------------------------------------------------------
424 
425 
426 class AbraClass : public QListWidget
427 {
428 public:
429  AbraClass(QWidget* parent) : QListWidget(parent) {}
430 protected:
431  void dropEvent(QDropEvent *event)
432  {
433 // QListWidgetItem* pos = NULL;
434 
435  if (event->source()==this)
436  {
437  std::cout << "drop this: " << event->mimeData()->formats().join(",") << std::endl;
438  event->setDropAction(Qt::MoveAction);
439  }
440 
441  QString newUid;
442  if (event->mimeData()->hasFormat("application/x-qabstractitemmodeldatalist"))
443  {
444  QByteArray itemData = event->mimeData()->data("application/x-qabstractitemmodeldatalist");
445  QDataStream stream(&itemData, QIODevice::ReadOnly);
446  int r, c;
447  QMap<int, QVariant> v;
448  stream >> r >> c >> v;
449  std::cout << "var: " << r << " " << c << " " << v.size() << std::endl;
450  if (!v.empty())
451  {
452  std::cout << "v: " << " " << v.begin()->typeName() << " " << v.begin()->toString() << std::endl;
453  newUid = v.begin()->toString();
454  }
455  }
456 
457  QListWidgetItem* itemToDelete = 0;
458  for(int i=0; i < this->count(); ++i)
459  {
460  QListWidgetItem* item = this->item(i);
461  if (item->text()==newUid)
462  itemToDelete = item;
463  }
464 
465  // std:: cout << "received dropEvent: " << event->mimeData()->text() << std::endl;
466 // this->populateData(event->mimeData()->text(), false, pos);
467 // event->setDropAction(Qt::MoveAction);
468 // event->accept();
469  std::cout << "dropaction " << event->dropAction() << std::endl;
470  QListWidget::dropEvent(event);
471  if (event->source()!=this) // remove old item if new if moved in from external source
472  delete itemToDelete;
473  }
474 
475 };
476 
477 class TestClass : public QListWidget
478 {
479 public:
480  TestClass(QWidget* parent) : QListWidget(parent) {}
481 protected:
482  void dropEvent(QDropEvent *event)
483  {
484  // ignore drop
485  event->setDropAction(Qt::MoveAction);
486  event->acceptProposedAction();
487 // QListWidget::dropEvent(event);
488  }
489 
490 };
491 
493  mViewService(viewService)
494 {
495  // TODO Auto-generated constructor stub
496  QHBoxLayout* layout = new QHBoxLayout(this);
497 
498  mSelectedDataListWidget = new SelectedDataListWidget(patientModelService, this);
499  mAllDataListWidget = new AllDataListWidget(patientModelService, this);
500 #if 0
501  TestClass* test = new TestClass(this);
502  test->addItem("test1");
503  test->addItem("test2");
504  test->addItem("test3");
505  test->addItem("test4");
506  //test->setDragDropMode(QAbstractItemView::InternalMove);
507  test->setDropIndicatorShown(false);
508  test->setDragEnabled(true);
509  test->setAcceptDrops(true);
510 
511  AbraClass* abra = new AbraClass(this);
512  abra->addItem("abra1");
513  abra->addItem("abra2");
514  abra->addItem("abra3");
515  abra->addItem("abra4");
516 // abra->setDragDropMode(QAbstractItemView::InternalMove);
517  abra->setDropIndicatorShown(true);
518  abra->setDragEnabled(true);
519  abra->setAcceptDrops(true);
520  abra->viewport()->setAcceptDrops(true);
521  abra->setDragDropOverwriteMode(true);
522 
523  layout->addWidget(test);
524  layout->addWidget(abra);
525 #endif
526 
527  QVBoxLayout* selLayout = new QVBoxLayout;
528  mVisibleLabel = new QLabel("Visible", this);
529  selLayout->addWidget(mVisibleLabel);
530  selLayout->addWidget(mSelectedDataListWidget);
531  layout->addLayout(selLayout);
532 
533  QVBoxLayout* allLayout = new QVBoxLayout;
534  allLayout->addWidget(new QLabel("All"));
535  allLayout->addWidget(mAllDataListWidget);
536  layout->addLayout(allLayout);
537 
538  connect(mViewService.get(), SIGNAL(activeViewChanged()), this, SLOT(viewGroupChangedSlot()));
539  this->viewGroupChangedSlot();
540 }
541 
542 void DataViewSelectionWidget::viewGroupChangedSlot()
543 {
544  int vg = mViewService->getActiveGroupId();
545  if (vg<0)
546  vg = 0;
547 
548  ViewGroupDataPtr group = mViewService->getGroup(vg);
549  if (group)
550  mSelectedDataListWidget->setViewGroupData(group);
551 
552  mVisibleLabel->setText("Visible in group "+qstring_cast(vg));
553 }
554 
555 
557 {
558  // TODO Auto-generated destructor stub
559 }
560 
561 }
QString qstring_cast(const T &val)
boost::shared_ptr< class ViewGroupData > ViewGroupDataPtr
Definition: cxViewGroup.h:50
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:42
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)
cxLogicManager_EXPORT ViewServicePtr viewService()
AllDataListWidget(PatientModelServicePtr patientModelService, QWidget *parent=NULL)
DataListWidget(PatientModelServicePtr patientModelService, QWidget *parent=NULL)
PatientModelServicePtr mPatientModelService
void reportDebug(QString msg)
Definition: cxLogger.cpp:89