| 
					
				 | 
			
			
				@@ -75,6 +75,7 @@ public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   QSharedPointer<ctkDICOMIndexer> DICOMIndexer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   QProgressDialog *IndexerProgress; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   QProgressDialog *UpdateSchemaProgress; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  QProgressDialog *ExportProgress; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void showIndexerDialog(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void showUpdateSchemaDialog(); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -99,6 +100,7 @@ ctkDICOMBrowserPrivate::ctkDICOMBrowserPrivate(ctkDICOMBrowser* parent): q_ptr(p 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   DICOMIndexer = QSharedPointer<ctkDICOMIndexer> (new ctkDICOMIndexer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   IndexerProgress = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   UpdateSchemaProgress = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ExportProgress = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   DisplayImportSummary = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   PatientsAddedDuringImport = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   StudiesAddedDuringImport = 0; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -116,6 +118,10 @@ ctkDICOMBrowserPrivate::~ctkDICOMBrowserPrivate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     delete UpdateSchemaProgress; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if ( ExportProgress ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    delete ExportProgress; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 void ctkDICOMBrowserPrivate::showUpdateSchemaDialog() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -669,7 +675,7 @@ void ctkDICOMBrowser::onModelSelected(const QItemSelection &item1, const QItemSe 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-bool ctkDICOMBrowser::confirmDeleteSelectedIUDs(QStringList uids) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+bool ctkDICOMBrowser::confirmDeleteSelectedUIDs(QStringList uids) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   Q_D(ctkDICOMBrowser); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -753,12 +759,19 @@ void ctkDICOMBrowser::onPatientsRightClicked(const QPoint &point) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   patientsMenu->addAction(deleteAction); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  QString exportString = QString("Export ") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    + QString::number(numPatients) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    + QString(" selected patients to file system"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  QAction *exportAction = new QAction(exportString, patientsMenu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  patientsMenu->addAction(exportAction); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // the table took care of mapping it to a global position so that the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // menu will pop up at the correct place over this table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   QAction *selectedAction = patientsMenu->exec(point); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (selectedAction == deleteAction 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      && this->confirmDeleteSelectedIUDs(selectedPatientsUIDs)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      && this->confirmDeleteSelectedUIDs(selectedPatientsUIDs)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     qDebug() << "Deleting " << numPatients << " patients"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     foreach (const QString& uid, selectedPatientsUIDs) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -766,6 +779,21 @@ void ctkDICOMBrowser::onPatientsRightClicked(const QPoint &point) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       d->DICOMDatabase->removePatient(uid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else if (selectedAction == exportAction) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctkFileDialog* directoryDialog = new ctkFileDialog(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    directoryDialog->setOption(QFileDialog::DontUseNativeDialog); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    directoryDialog->setOption(QFileDialog::ShowDirsOnly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    directoryDialog->setFileMode(QFileDialog::DirectoryOnly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bool res = directoryDialog->exec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (res) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      QStringList dirs = directoryDialog->selectedFiles(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      QString dirPath = dirs[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->exportSelectedPatients(dirPath, selectedPatientsUIDs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    delete directoryDialog; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //---------------------------------------------------------------------------- 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -791,18 +819,40 @@ void ctkDICOMBrowser::onStudiesRightClicked(const QPoint &point) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   studiesMenu->addAction(deleteAction); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  QString exportString = QString("Export ") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    + QString::number(numStudies) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    + QString(" selected studies to file system"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  QAction *exportAction = new QAction(exportString, studiesMenu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  studiesMenu->addAction(exportAction); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // the table took care of mapping it to a global position so that the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // menu will pop up at the correct place over this table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   QAction *selectedAction = studiesMenu->exec(point); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (selectedAction == deleteAction 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      && this->confirmDeleteSelectedIUDs(selectedStudiesUIDs)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      && this->confirmDeleteSelectedUIDs(selectedStudiesUIDs)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     foreach (const QString& uid, selectedStudiesUIDs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       d->DICOMDatabase->removeStudy(uid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else if (selectedAction == exportAction) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctkFileDialog* directoryDialog = new ctkFileDialog(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    directoryDialog->setOption(QFileDialog::DontUseNativeDialog); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    directoryDialog->setOption(QFileDialog::ShowDirsOnly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    directoryDialog->setFileMode(QFileDialog::DirectoryOnly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bool res = directoryDialog->exec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (res) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      QStringList dirs = directoryDialog->selectedFiles(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      QString dirPath = dirs[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->exportSelectedStudies(dirPath, selectedStudiesUIDs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    delete directoryDialog; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //---------------------------------------------------------------------------- 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -828,16 +878,203 @@ void ctkDICOMBrowser::onSeriesRightClicked(const QPoint &point) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   seriesMenu->addAction(deleteAction); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  QString exportString = QString("Export ") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    + QString::number(numSeries) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    + QString(" selected series to file system"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  QAction *exportAction = new QAction(exportString, seriesMenu); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  seriesMenu->addAction(exportAction); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // the table took care of mapping it to a global position so that the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // menu will pop up at the correct place over this table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   QAction *selectedAction = seriesMenu->exec(point); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   if (selectedAction == deleteAction 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      && this->confirmDeleteSelectedIUDs(selectedSeriesUIDs)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      && this->confirmDeleteSelectedUIDs(selectedSeriesUIDs)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     foreach (const QString& uid, selectedSeriesUIDs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       d->DICOMDatabase->removeSeries(uid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  else if (selectedAction == exportAction) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctkFileDialog* directoryDialog = new ctkFileDialog(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    directoryDialog->setOption(QFileDialog::DontUseNativeDialog); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    directoryDialog->setOption(QFileDialog::ShowDirsOnly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    directoryDialog->setFileMode(QFileDialog::DirectoryOnly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    bool res = directoryDialog->exec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (res) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      QStringList dirs = directoryDialog->selectedFiles(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      QString dirPath = dirs[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this->exportSelectedSeries(dirPath, selectedSeriesUIDs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    delete directoryDialog; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void ctkDICOMBrowser::exportSelectedSeries(QString dirPath, QStringList uids) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Q_D(ctkDICOMBrowser); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  foreach (const QString& uid, uids) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QStringList filesForSeries = d->DICOMDatabase->filesForSeries(uid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Use the first file to get the overall series information 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString firstFilePath = filesForSeries[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QHash<QString,QString> descriptions (d->DICOMDatabase->descriptionsForFile(firstFilePath)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString patientName = descriptions["PatientsName"]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString patientIDTag = QString("0010,0020"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString patientID = d->DICOMDatabase->fileValue(firstFilePath, patientIDTag); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString studyDescription = descriptions["StudyDescription"]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString seriesDescription = descriptions["SeriesDescription"]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString studyDateTag = QString("0008,0020"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString studyDate = d->DICOMDatabase->fileValue(firstFilePath,studyDateTag); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString seriesNumberTag = QString("0020,0011"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString seriesNumber = d->DICOMDatabase->fileValue(firstFilePath,seriesNumberTag); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString sep = "/"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString nameSep = "-"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QString destinationDir = dirPath + sep + patientID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!patientName.isEmpty()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      destinationDir += nameSep + patientName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    destinationDir += sep + studyDate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!studyDescription.isEmpty()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      destinationDir += nameSep + studyDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    destinationDir += sep + seriesNumber; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!seriesDescription.isEmpty()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      destinationDir += nameSep + seriesDescription; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    destinationDir += sep; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // make sure only ascii characters are in the directory path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    destinationDir = destinationDir.toLatin1(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // replace any question marks that were used as replacements for non ascii 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // characters with underscore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    destinationDir.replace("?", "_"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // create the destination directory if necessary 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!QDir().exists(destinationDir)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!QDir().mkpath(destinationDir)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        QString errorString = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          QString("Unable to create export destination directory:\n\n") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          + destinationDir 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          + QString("\n\nHalting export."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctkMessageBox createDirectoryErrorMessageBox; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createDirectoryErrorMessageBox.setText(errorString); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createDirectoryErrorMessageBox.setIcon(QMessageBox::Warning); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        createDirectoryErrorMessageBox.exec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // show progress 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (d->ExportProgress == 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      d->ExportProgress = new QProgressDialog(this->tr("DICOM Export"), "Close", 0, 100, this, Qt::WindowTitleHint | Qt::WindowSystemMenuHint); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      d->ExportProgress->setWindowModality(Qt::ApplicationModal); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      d->ExportProgress->setMinimumDuration(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QLabel *exportLabel = new QLabel(this->tr("Exporting series ") + seriesNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    d->ExportProgress->setLabel(exportLabel); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    d->ExportProgress->setValue(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int fileNumber = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    int numFiles = filesForSeries.size(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    d->ExportProgress->setMaximum(numFiles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    foreach (const QString& filePath, filesForSeries) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      QString destinationFileName = destinationDir; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      QString fileNumberString; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // sequentially number the files 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      fileNumberString.sprintf("%06d", fileNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      destinationFileName += fileNumberString + QString(".dcm"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // replace non ASCII characters 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      destinationFileName = destinationFileName.toLatin1(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // replace any question marks that were used as replacements for non ascii 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // characters with underscore 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      destinationFileName.replace("?", "_"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!QFile::exists(filePath)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        d->ExportProgress->setValue(numFiles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        QString errorString = QString("Export source file not found:\n\n") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          + filePath 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          + QString("\n\nHalting export.\n\nError may be fixed via Repair."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctkMessageBox copyErrorMessageBox; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        copyErrorMessageBox.setText(errorString); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        copyErrorMessageBox.setIcon(QMessageBox::Warning); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        copyErrorMessageBox.exec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (QFile::exists(destinationFileName)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        d->ExportProgress->setValue(numFiles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        QString errorString = QString("Export destination file already exists:\n\n") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          + destinationFileName 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          + QString("\n\nHalting export."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctkMessageBox copyErrorMessageBox; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        copyErrorMessageBox.setText(errorString); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        copyErrorMessageBox.setIcon(QMessageBox::Warning); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        copyErrorMessageBox.exec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      bool copyResult = QFile::copy(filePath, destinationFileName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!copyResult) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        d->ExportProgress->setValue(numFiles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        QString errorString = QString("Failed to copy\n\n") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          + filePath 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          + QString("\n\nto\n\n") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          + destinationFileName 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          + QString("\n\nHalting export."); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctkMessageBox copyErrorMessageBox; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        copyErrorMessageBox.setText(errorString); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        copyErrorMessageBox.setIcon(QMessageBox::Warning); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        copyErrorMessageBox.exec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      fileNumber++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      d->ExportProgress->setValue(fileNumber); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    d->ExportProgress->setValue(numFiles); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void ctkDICOMBrowser::exportSelectedStudies(QString dirPath, QStringList uids) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Q_D(ctkDICOMBrowser); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  foreach (const QString& uid, uids) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QStringList seriesUIDs = d->DICOMDatabase->seriesForStudy(uid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->exportSelectedSeries(dirPath, seriesUIDs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+//---------------------------------------------------------------------------- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+void ctkDICOMBrowser::exportSelectedPatients(QString dirPath, QStringList uids) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Q_D(ctkDICOMBrowser); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  foreach (const QString& uid, uids) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    QStringList studiesUIDs = d->DICOMDatabase->studiesForPatient(uid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->exportSelectedStudies(dirPath, studiesUIDs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |