CustusX  2023.01.05-dev+develop.0da12
An IGT application
cxDICOMAppWidget.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Library: CTK
4 
5  Copyright (c) Kitware Inc.
6 
7  Licensed under the Apache License, Version 2.0 (the "License");
8  you may not use this file except in compliance with the License.
9  You may obtain a copy of the License at
10 
11  http://www.apache.org/licenses/LICENSE-2.0.txt
12 
13  Unless required by applicable law or agreed to in writing, software
14  distributed under the License is distributed on an "AS IS" BASIS,
15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  See the License for the specific language governing permissions and
17  limitations under the License.
18 
19 =========================================================================*/
20 
21 // std includes
22 #include <iostream>
23 
24 #include <dcmimage.h>
25 
26 // Qt includes
27 #include <QAction>
28 #include <QCoreApplication>
29 #include <QCheckBox>
30 #include <QDebug>
31 #include <QMessageBox>
32 #include <QMetaType>
33 #include <QModelIndex>
34 #include <QPersistentModelIndex>
35 #include <QProgressDialog>
36 #include <QSettings>
37 #include <QSlider>
38 #include <QTabBar>
39 #include <QTimer>
40 #include <QTreeView>
41 #include <QLabel>
42 #include <QHBoxLayout>
43 #include <QSplitter>
44 
45 // ctkWidgets includes
46 #include "ctkDirectoryButton.h"
47 #include "ctkFileDialog.h"
48 
49 // ctkDICOMCore includes
50 #include "ctkDICOMDatabase.h"
51 #include "ctkDICOMFilterProxyModel.h"
52 #include "ctkDICOMIndexer.h"
53 #include "cxDICOMModel.h"
54 
55 // ctkDICOMWidgets includes
56 #include "cxDICOMAppWidget.h"
58 #include "ctkThumbnailLabel.h"
59 #include "ctkDICOMQueryResultsTabWidget.h"
60 #include "ctkDICOMQueryRetrieveWidget.h"
61 #include "ctkDICOMQueryWidget.h"
62 #include <QToolBar>
63 //#include "ctkDICOMThumbnailListWidget.h"
65 
66 
67 #include "cxDicomImporter.h"
68 #include "cxLogger.h"
69 
70 //#include "ui_DICOMAppWidget.h"
71 
72 //logger
73 #include <ctkLogger.h>
74 static ctkLogger logger("org.commontk.DICOM.Widgets.DICOMAppWidget");
75 
76 Q_DECLARE_METATYPE(QPersistentModelIndex);
77 
78 
79 namespace cx
80 {
82 
83 //----------------------------------------------------------------------------
84 class DICOMAppWidgetPrivate: public QWidget
85 {
86 public:
89 
92  void setupUi(DICOMAppWidget* parent);
93 
94  QVBoxLayout* TopLayout;
95  QTreeView* TreeView;
96  QToolBar* ToolBar;
97 // ctkDICOMThumbnailListWidget* ThumbnailsWidget;
100  QAction* ActionImport;
101  QAction* ActionQuery;
102  QAction* ActionRemove;
103  QList<QAction*> mAdvancedActions;
105 
106  ctkDICOMQueryRetrieveWidget* QueryRetrieveWidget;
107  ctkDICOMQueryRetrieveWidget* getQueryRetrieveWidget();
108 
109  QSharedPointer<ctkDICOMDatabase> DICOMDatabase;
110  QSharedPointer<ctkDICOMThumbnailGenerator> ThumbnailGenerator;
111  ctkDICOMModel mDICOMModel;
112  ctkDICOMFilterProxyModel DICOMProxyModel;
113  QProgressDialog *UpdateSchemaProgress;
114 
115  void showUpdateSchemaDialog();
116  std::map<ctkDICOMModel::IndexType, QStringList> getSelection() const;
117 
118  void removeSelection();
119 };
120 
121 //----------------------------------------------------------------------------
122 // DICOMAppWidgetPrivate methods
123 
125  q_ptr(parent),
126  TopLayout(NULL),
127  TreeView(NULL),
128  ToolBar(NULL),
129  ThumbnailsWidget(NULL),
130  ThumbnailWidthSlider(NULL),
131  ActionImport(NULL),
132  ActionQuery(NULL),
133  ActionRemove(NULL),
134  QueryRetrieveWidget(NULL)
135 {
136  DICOMDatabase = QSharedPointer<ctkDICOMDatabase> (new ctkDICOMDatabase);
137  ThumbnailGenerator = QSharedPointer <ctkDICOMThumbnailGenerator> (new ctkDICOMThumbnailGenerator);
138  DICOMDatabase->setThumbnailGenerator(ThumbnailGenerator.data());
140 }
141 
143 {
144  if ( UpdateSchemaProgress )
145  {
146  delete UpdateSchemaProgress;
147  }
148 
150  QueryRetrieveWidget->deleteLater();
151 }
152 
154 {
155  Q_Q(DICOMAppWidget);
156 
157  TopLayout = new QVBoxLayout(parent);
158  TopLayout->setMargin(0);
159 
160  ToolBar = new QToolBar;
161  TopLayout->addWidget(ToolBar);
162 
163  ActionImport = new QAction("Open file(s)", this);
164  QString helpText = "Open a DICOM file or folder and make it ready for import";
165  ActionImport->setToolTip(helpText);
166  ActionImport->setStatusTip(helpText);
167  ActionImport->setIcon(QIcon(":/icons/open_icon_library/document-open-7.png"));
168  q->connect(ActionImport, SIGNAL(triggered()), &Importer, SLOT(openImportDialog()));
169  ToolBar->addAction(ActionImport);
170 
171  ActionRemove = new QAction("Remove", this);
172  helpText = "Remove the selected series";
173  ActionRemove->setToolTip(helpText);
174  ActionRemove->setStatusTip(helpText);
175  ActionRemove->setIcon(QIcon(":/icons/open_icon_library/dialog-close.png"));
176  q->connect(ActionRemove, SIGNAL(triggered()), q, SLOT(onRemoveAction()));
178  ToolBar->addAction(ActionRemove);
179 
180  ActionQuery = new QAction("Query", this);
181  helpText = "Query and Retrieve DICOM studies from a DICOM database";
182  ActionQuery->setToolTip(helpText);
183  ActionQuery->setStatusTip(helpText);
184  ActionQuery->setIcon(QIcon(":/icons/message_levels/dialog-information-4.png"));
185  q->connect(ActionQuery, SIGNAL(triggered()), q, SLOT(openQueryDialog()));
187  ToolBar->addAction(ActionQuery);
188 
189  QSplitter* splitter = new QSplitter;
190  splitter->setOrientation(Qt::Vertical);
191  TopLayout->addWidget(splitter);
192 
193  TreeView = new QTreeView;
194  TreeView->setAlternatingRowColors(true);
195  splitter->addWidget(TreeView);
196 
197  QWidget* ThumbnailsFullWidget = new QWidget;
198  splitter->addWidget(ThumbnailsFullWidget);
199  QVBoxLayout* ThumbnailsFullWidgetLayout = new QVBoxLayout(ThumbnailsFullWidget);
200  ThumbnailsFullWidgetLayout->setMargin(0);
201 
203  ThumbnailsWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
204  ThumbnailsWidget->setMinimumSize(QSize(0,200));
205  ThumbnailsFullWidgetLayout->addWidget(ThumbnailsWidget);
206 
207  ThumbnailWidthSlider = new QSlider;
208  ThumbnailWidthSlider->setMinimum(64);
209  ThumbnailWidthSlider->setMaximum(256);
210  ThumbnailWidthSlider->setValue(64);
211  ThumbnailWidthSlider->setOrientation(Qt::Horizontal);
212  connect(ThumbnailWidthSlider, SIGNAL(valueChanged(int)), q, SLOT(onThumbnailWidthSliderValueChanged(int)));
213  ThumbnailsFullWidgetLayout->addWidget(ThumbnailWidthSlider);
214 }
215 
217 {
218  Q_Q(DICOMAppWidget);
219 
220  ctkDICOMDatabase* db = DICOMDatabase.data();
221  q->connect(db, SIGNAL(schemaUpdateStarted(int)), q, SLOT(schemaUpdateStarted(int)));
222  q->connect(db, SIGNAL(schemaUpdateProgress(int)), q, SLOT(schemaUpdateProgress(int)));
223  q->connect(db, SIGNAL(schemaUpdateProgress(QString)), q, SLOT(schemaUpdateProgress(QString)));
224  q->connect(db, SIGNAL(schemaUpdated()), q, SLOT(schemaUpdated()));
225 
226 // if (UpdateSchemaProgress == 0)
227 // {
228 // //
229 // // Set up the Update Schema Progress Dialog
230 // //
231 // UpdateSchemaProgress = new QProgressDialog(
232 // q->tr("DICOM Schema Update"), "Cancel", 0, 100, q,
233 // Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
234 
235 // // We don't want the progress dialog to resize itself, so we bypass the label
236 // // by creating our own
237 // QLabel* progressLabel = new QLabel(q->tr("Initialization..."));
238 // UpdateSchemaProgress->setLabel(progressLabel);
239 // UpdateSchemaProgress->setWindowModality(Qt::ApplicationModal);
240 // UpdateSchemaProgress->setMinimumDuration(0);
241 // UpdateSchemaProgress->setValue(0);
242 
243 // //q->connect(UpdateSchemaProgress, SIGNAL(canceled()),
244 // // DICOMIndexer.data(), SLOT(cancel()));
245 // ctkDICOMDatabase* db = DICOMDatabase.data();
246 
247 // q->connect(db, SIGNAL(schemaUpdateStarted(int)), UpdateSchemaProgress, SLOT(setMaximum(int)));
248 // q->connect(db, SIGNAL(schemaUpdateProgress(int)), UpdateSchemaProgress, SLOT(setValue(int)));
249 // q->connect(db, SIGNAL(schemaUpdateProgress(QString)), progressLabel, SLOT(setText(QString)));
250 // // close the dialog
252 // // reset the database to show new data
253 // q->connect(db, SIGNAL(schemaUpdated()), &mDICOMModel, SLOT(reset()));
254 // // reset the database if canceled
255 // q->connect(UpdateSchemaProgress, SIGNAL(canceled()), &mDICOMModel, SLOT(reset()));
256 
257 
258 // q->connect(db, SIGNAL(schemaUpdateStarted(int)), q, SLOT(schemaUpdateStarted(int)));
259 // q->connect(db, SIGNAL(schemaUpdateProgress(int)), q, SLOT(schemaUpdateProgress(int)));
260 // q->connect(db, SIGNAL(schemaUpdateProgress(QString)), q, SLOT(schemaUpdateProgress(QString)));
261 // q->connect(db, SIGNAL(schemaUpdated()), q, SLOT(schemaUpdated()));
262 // }
263 // UpdateSchemaProgress->show();
264 }
265 
266 void DICOMAppWidget::schemaUpdateStarted(int)
267 {
268 // report("DICOM schema update started...");
269 }
270 void DICOMAppWidget::schemaUpdateProgress(QString val)
271 {
272 }
273 void DICOMAppWidget::schemaUpdateProgress(int val)
274 {
275 }
276 void DICOMAppWidget::schemaUpdated()
277 {
278 // report("DICOM schema updated");
279 }
280 
282 {
283  QModelIndexList selection = TreeView->selectionModel()->selectedIndexes();
284  QModelIndex index;
285 
286  foreach(index,selection)
287  {
288  if (index.column()!=0)
289  continue;
290  mDICOMModel.removeRows(index.row(), 1, index.parent());
291 // this->remove(index);
292  }
293 }
294 
295 std::map<ctkDICOMModel::IndexType, QStringList> DICOMAppWidgetPrivate::getSelection() const
296 {
297 // Q_Q(DICOMAppWidget);
298  std::map<ctkDICOMModel::IndexType, QStringList> retval;
299  QModelIndexList selection = TreeView->selectionModel()->selectedIndexes();
300  QModelIndex index;
301 
302  foreach(index,selection)
303  {
304  QModelIndex index0 = index.sibling(index.row(), 0);
306  QString uid = mDICOMModel.data(index0,ctkDICOMModel::UIDRole).toString();
307 
308  retval[type] << uid;
309  retval[type].removeDuplicates();
310  }
311 
312  return retval;
313 }
314 
315 //----------------------------------------------------------------------------
316 ctkDICOMQueryRetrieveWidget* DICOMAppWidgetPrivate::getQueryRetrieveWidget()
317 {
318  if (!QueryRetrieveWidget)
319  {
320  Q_Q(DICOMAppWidget);
321  //Initialize Q/R widget
322  QueryRetrieveWidget = new ctkDICOMQueryRetrieveWidget();
323  QueryRetrieveWidget->setWindowModality(Qt::ApplicationModal);
324 
325  connect(QueryRetrieveWidget, SIGNAL(canceled()), QueryRetrieveWidget, SLOT(hide()) );
326  connect(QueryRetrieveWidget, SIGNAL(canceled()), q, SLOT(onQueryRetrieveFinished()) );
327 
328  QueryRetrieveWidget->setRetrieveDatabase(DICOMDatabase);
329  }
330 
331  return QueryRetrieveWidget;
332 }
333 
334 //----------------------------------------------------------------------------
335 // DICOMAppWidget methods
336 
337 //----------------------------------------------------------------------------
338 DICOMAppWidget::DICOMAppWidget(QWidget* _parent):Superclass(_parent),
339  d_ptr(new DICOMAppWidgetPrivate(this))
340 {
341  Q_D(DICOMAppWidget);
342 
343  d->setupUi(this);
344 
345  connect(&d->Importer, SIGNAL(indexingCompleted()),
346  &d->mDICOMModel, SLOT(reset()));
347  connect(&d->Importer, SIGNAL(directoryImported()),
348  this, SIGNAL(directoryImported()));
349 
350  //Enable sorting in tree view
351  d->TreeView->setSortingEnabled(true);
352  d->TreeView->setSelectionBehavior(QAbstractItemView::SelectRows);
353  d->TreeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
354  d->DICOMProxyModel.setSourceModel(&d->mDICOMModel);
355  d->TreeView->setModel(&d->mDICOMModel);
356 
357  d->ThumbnailsWidget->setThumbnailSize(
358  QSize(d->ThumbnailWidthSlider->value(), d->ThumbnailWidthSlider->value()));
359 
360  // Treeview signals
361  connect(d->TreeView, SIGNAL(collapsed(QModelIndex)), this, SLOT(onTreeCollapsed(QModelIndex)));
362  connect(d->TreeView, SIGNAL(expanded(QModelIndex)), this, SLOT(onTreeExpanded(QModelIndex)));
363 
364  //Set ToolBar button style
365  d->ToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
366 
367 // //Initialize Q/R widget
368 // d->QueryRetrieveWidget = new ctkDICOMQueryRetrieveWidget();
369 // d->QueryRetrieveWidget->setWindowModality ( Qt::ApplicationModal );
370 
371  connect(d->TreeView->selectionModel(),
372  &QItemSelectionModel::selectionChanged,
373  this,
375  connect(d->TreeView->selectionModel(),
376  &QItemSelectionModel::currentChanged,
377  this,
379 
380  //connect signal and slots
381  connect(d->TreeView, SIGNAL(clicked(QModelIndex)), this, SLOT(onModelSelected(QModelIndex)));
382 
383 // connect(d->QueryRetrieveWidget, SIGNAL(canceled()), d->QueryRetrieveWidget, SLOT(hide()) );
384 // connect(d->QueryRetrieveWidget, SIGNAL(canceled()), this, SLOT(onQueryRetrieveFinished()) );
385 }
386 
387 //----------------------------------------------------------------------------
389 {
390  Q_D(DICOMAppWidget);
391 
392 // d->QueryRetrieveWidget->deleteLater();
393 }
394 
395 //----------------------------------------------------------------------------
397 {
398  Q_D(DICOMAppWidget);
399  return d->Importer.displayImportSummary();
400 }
401 
402 //----------------------------------------------------------------------------
404 {
405  Q_D(DICOMAppWidget);
406  return d->Importer.setDisplayImportSummary(onOff);
407 }
408 
409 //----------------------------------------------------------------------------
411 {
412  Q_D(DICOMAppWidget);
413  return d->Importer.patientsAddedDuringImport();
414 }
415 
416 //----------------------------------------------------------------------------
418 {
419  Q_D(DICOMAppWidget);
420  return d->Importer.studiesAddedDuringImport();
421 }
422 
423 //----------------------------------------------------------------------------
425 {
426  Q_D(DICOMAppWidget);
427  return d->Importer.seriesAddedDuringImport();
428 }
429 
430 //----------------------------------------------------------------------------
432 {
433  Q_D(DICOMAppWidget);
434  return d->Importer.instancesAddedDuringImport();
435 }
436 
437 //----------------------------------------------------------------------------
439 {
440  Q_D(DICOMAppWidget);
441 
442  d->showUpdateSchemaDialog();
443  d->DICOMDatabase->updateSchemaIfNeeded();
444 }
445 
446 //----------------------------------------------------------------------------
447 void DICOMAppWidget::setDatabaseDirectory(const QString& directory)
448 {
449  Q_D(DICOMAppWidget);
450 
451  QSettings settings;
452  settings.setValue("DatabaseDirectory", directory);
453  settings.sync();
454 
455  //close the active DICOM database
456  d->DICOMDatabase->closeDatabase();
457 
458  //open DICOM database on the directory
459  QString databaseFileName = directory + QString("/ctkDICOM.sql");
460  try
461  {
462  d->DICOMDatabase->openDatabase( databaseFileName );
463 
464  CX_LOG_CHANNEL_INFO("dicom") << "Open Database " << databaseFileName.toStdString() << ", open= " << d->DICOMDatabase->isOpen();
465 // std::cout << "open database " << databaseFileName.toStdString() << ", open= " << d->DICOMDatabase->isOpen() << std::endl;
466  }
467  catch (std::exception& e)
468  {
469  CX_LOG_CHANNEL_ERROR("dicom") << "Database error: " << qPrintable(d->DICOMDatabase->lastError());
470 // std::cerr << "Database error: " << qPrintable(d->DICOMDatabase->lastError()) << "\n";
471  d->DICOMDatabase->closeDatabase();
472  return;
473  }
474 
475  // update the database schema if needed and provide progress
477 
478  d->mDICOMModel.setDatabase(d->DICOMDatabase);
479  d->mDICOMModel.setEndLevel(ctkDICOMModel::SeriesType);
480  d->TreeView->resizeColumnToContents(0);
481  d->Importer.setDatabase(d->DICOMDatabase);
482 
483 // d->getQueryRetrieveWidget()->setRetrieveDatabase(d->DICOMDatabase);
484  d->ThumbnailsWidget->setDatabaseDirectory(directory);
485  d->ThumbnailsWidget->setDatabase(d->DICOMDatabase);
486  emit databaseDirectoryChanged(directory);
487 }
488 
489 //----------------------------------------------------------------------------
491 {
492  QSettings settings;
493  return settings.value("DatabaseDirectory").toString();
494 }
495 
496 //------------------------------------------------------------------------------
497 void DICOMAppWidget::setTagsToPrecache( const QStringList tags)
498 {
499  Q_D(DICOMAppWidget);
500  d->DICOMDatabase->setTagsToPrecache(tags);
501 }
502 
503 //------------------------------------------------------------------------------
505 {
506  Q_D(DICOMAppWidget);
507  return d->DICOMDatabase->tagsToPrecache();
508 }
509 
510 //----------------------------------------------------------------------------
511 ctkDICOMDatabase* DICOMAppWidget::database(){
512  Q_D(DICOMAppWidget);
513  return d->DICOMDatabase.data();
514 }
515 
516 //----------------------------------------------------------------------------
518 {
519  Q_D(DICOMAppWidget);
520 
521  d->getQueryRetrieveWidget()->show();
522  d->getQueryRetrieveWidget()->raise();
523 
524 }
525 
526 //----------------------------------------------------------------------------
528 {
529  Q_D(DICOMAppWidget);
530  d->mDICOMModel.reset();
531  emit this->queryRetrieveFinished();
532 }
533 
535 {
536  Q_D(DICOMAppWidget);
537  return d->getSelection()[ctkDICOMModel::PatientType];
538 }
540 {
541  Q_D(DICOMAppWidget);
542  return d->getSelection()[ctkDICOMModel::StudyType];
543 }
545 {
546  Q_D(DICOMAppWidget);
547  return d->getSelection()[ctkDICOMModel::SeriesType];
548 }
549 
550 //----------------------------------------------------------------------------
552 {
553  Q_D(DICOMAppWidget);
554  d->removeSelection();
555 }
556 
557 //----------------------------------------------------------------------------
559 {
560  Q_D(DICOMAppWidget);
561  d->mDICOMModel.setDatabase(d->DICOMDatabase);
562 }
563 
564 //----------------------------------------------------------------------------
566 {
567  Q_D(DICOMAppWidget);
568  d->mDICOMModel.reset();
569 }
570 
572 void DICOMAppWidget::onImportDirectory(QString directory)
573 {
574  Q_D(DICOMAppWidget);
575  d->Importer.onImportDirectory(directory);
576 }
577 
578 void DICOMAppWidget::onSelectionChanged(const QItemSelection&, const QItemSelection&)
579 {
580 }
581 
582 void DICOMAppWidget::onCurrentChanged(const QModelIndex& next, const QModelIndex& last)
583 {
584  Q_D(DICOMAppWidget);
585  d->ThumbnailsWidget->addThumbnails(next);
586 }
587 
588 void DICOMAppWidget::onModelSelected(const QModelIndex &index)
589 {
590  Q_D(DICOMAppWidget);
591 
592  ctkDICOMModel* model = const_cast<ctkDICOMModel*>(qobject_cast<const ctkDICOMModel*>(index.model()));
593 
594  if(model)
595  {
596  QModelIndex index0 = index.sibling(index.row(), 0);
597 
598  d->ActionRemove->setEnabled(
599  model->data(index0,ctkDICOMModel::TypeRole) == static_cast<int>(ctkDICOMModel::SeriesType) ||
600  model->data(index0,ctkDICOMModel::TypeRole) == static_cast<int>(ctkDICOMModel::StudyType) ||
601  model->data(index0,ctkDICOMModel::TypeRole) == static_cast<int>(ctkDICOMModel::PatientType) );
602  }
603  else
604  {
605  d->ActionRemove->setEnabled(false);
606  }
607 }
608 
609 //----------------------------------------------------------------------------
610 void DICOMAppWidget::onTreeCollapsed(const QModelIndex &index){
611  Q_UNUSED(index);
612  Q_D(DICOMAppWidget);
613  d->TreeView->resizeColumnToContents(0);
614 }
615 
616 //----------------------------------------------------------------------------
617 void DICOMAppWidget::onTreeExpanded(const QModelIndex &index){
618  Q_UNUSED(index);
619  Q_D(DICOMAppWidget);
620  d->TreeView->resizeColumnToContents(0);
621  d->TreeView->resizeColumnToContents(1);
622 }
623 
624 //----------------------------------------------------------------------------
626 {
627  Q_D(DICOMAppWidget);
628  d->ThumbnailsWidget->setThumbnailSize(QSize(val, val));
629 }
630 
632 {
633  Q_D(DICOMAppWidget);
634  d->ToolBar->addAction(action);
635 }
636 
637 QList<QAction*> DICOMAppWidget::getAdvancedActions() const
638 {
639  return d_ptr->mAdvancedActions;
640 }
641 
642 
643 
644 } // namespace cx
#define CX_LOG_CHANNEL_INFO(channel)
Definition: cxLogger.h:108
void onTreeCollapsed(const QModelIndex &index)
ctkDICOMQueryRetrieveWidget * getQueryRetrieveWidget()
QStringList getSelectedSeries()
ctkDICOMQueryRetrieveWidget * QueryRetrieveWidget
Q_DECLARE_PUBLIC(DICOMAppWidget)
void onTreeExpanded(const QModelIndex &index)
virtual bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex())
DICOMAppWidgetPrivate(DICOMAppWidget *)
ctkDICOMDatabase * database()
ctkDICOMFilterProxyModel DICOMProxyModel
std::map< ctkDICOMModel::IndexType, QStringList > getSelection() const
void addActionToToolbar(QAction *action)
void setDisplayImportSummary(bool)
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
void onSelectionChanged(const QItemSelection &, const QItemSelection &)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: cxSettings.cpp:66
QSharedPointer< ctkDICOMDatabase > DICOMDatabase
QScopedPointer< DICOMAppWidgetPrivate > d_ptr
QList< QAction * > mAdvancedActions
QSharedPointer< ctkDICOMThumbnailGenerator > ThumbnailGenerator
void onImportDirectory(QString directory)
void setTagsToPrecache(const QStringList tags)
DICOMModel ctkDICOMModel
void setValue(const QString &key, const QVariant &value)
Definition: cxSettings.cpp:58
QStringList getSelectedPatients()
QStringList getSelectedStudies()
void onCurrentChanged(const QModelIndex &, const QModelIndex &)
void databaseDirectoryChanged(const QString &)
QProgressDialog * UpdateSchemaProgress
QString databaseDirectory() const
Directory being used to store the dicom database.
Settings * settings()
Shortcut for accessing the settings instance.
Definition: cxSettings.cpp:21
DICOMAppWidget(QWidget *parent=0)
void queryRetrieveFinished()
void onThumbnailWidthSliderValueChanged(int val)
QList< QAction * > getAdvancedActions() const
void setupUi(DICOMAppWidget *parent)
const QStringList tagsToPrecache()
void onModelSelected(const QModelIndex &index)
DICOMAppWidget *const q_ptr
void setDatabaseDirectory(const QString &directory)
Q_DECLARE_METATYPE(QPersistentModelIndex)
int patientsAddedDuringImport()
Accessors to status of last directory import operation.
#define CX_LOG_CHANNEL_ERROR(channel)
Definition: cxLogger.h:111
DICOMThumbnailListWidget * ThumbnailsWidget
Namespace for all CustusX production code.