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 #ifndef __ctkDICOMIndexer_h 22 #define __ctkDICOMIndexer_h 23 24 // Qt includes 25 #include <QObject> 26 #include <QSqlDatabase> 27 28 #include "ctkDICOMCoreExport.h" 29 #include "ctkDICOMDatabase.h" 30 31 class ctkDICOMIndexerPrivate; 32 33 /// \ingroup DICOM_Core 34 /// 35 /// \brief Indexes DICOM images located in local directory into an Sql database 36 /// 37 class CTK_DICOM_CORE_EXPORT ctkDICOMIndexer : public QObject 38 { 39 Q_OBJECT 40 public: 41 explicit ctkDICOMIndexer(QObject *parent = 0); 42 virtual ~ctkDICOMIndexer(); 43 44 /// 45 /// \brief Adds directory to database and optionally copies files to 46 /// destinationDirectory. 47 /// 48 /// Scan the directory using Dcmtk and populate the database with all the 49 /// DICOM images accordingly. 50 /// 51 /// If includeHidden is set to false then hidden files and folders are not added. 52 /// DICOM folders may be created based on series or study name, which sometimes start 53 /// with a . character, therefore it is advisable to include hidden files and folders. 54 /// 55 Q_INVOKABLE void addDirectory(ctkDICOMDatabase& database, const QString& directoryName, 56 const QString& destinationDirectoryName = "", bool includeHidden = true); 57 58 /// 59 /// \brief Adds directory to database by using DICOMDIR and optionally copies files to 60 /// destinationDirectory. 61 /// Scan the directory using Dcmtk and populate the database with all the 62 /// DICOM images accordingly. 63 /// \return Returns false if there was an error while processing the DICOMDIR file. 64 /// 65 Q_INVOKABLE bool addDicomdir(ctkDICOMDatabase& database, const QString& directoryName, 66 const QString& destinationDirectoryName = ""); 67 68 /// 69 /// \brief Adds a QStringList containing the file path to database and optionally copies files to 70 /// destinationDirectory. 71 /// 72 /// Scan the directory using Dcmtk and populate the database with all the 73 /// DICOM images accordingly. 74 /// 75 Q_INVOKABLE void addListOfFiles(ctkDICOMDatabase& database, const QStringList& listOfFiles, 76 const QString& destinationDirectoryName = ""); 77 78 /// 79 /// \brief Adds a file to database and optionally copies the file to 80 /// destinationDirectory. 81 /// 82 /// Scan the file using Dcmtk and populate the database with all the 83 /// DICOM fields accordingly. 84 /// 85 Q_INVOKABLE void addFile(ctkDICOMDatabase& database, const QString filePath, 86 const QString& destinationDirectoryName = ""); 87 88 Q_INVOKABLE void refreshDatabase(ctkDICOMDatabase& database, const QString& directoryName); 89 90 /// 91 /// \brief Deprecated - no op. 92 /// \deprecated 93 /// Previously ensured that the QFuture threads have all finished indexing 94 /// before returning control. 95 /// 96 Q_INVOKABLE void waitForImportFinished(); 97 98 /// Call this before performing multiple add...() calls in one batch 99 /// to slightly increase indexing performance and to make only a single 100 /// indexingComplete() signal emitted for multiple add...() operations. 101 /// 102 /// If startIndexing() is called before a batch of insertions, then 103 /// endIndexing() method must be called after the insertions are completed. 104 /// 105 /// It is recommended to use ScopedIndexing helper class to call startIndexing 106 /// and endIndexing automatically. 107 Q_INVOKABLE void startIndexing(ctkDICOMDatabase& database); 108 109 /// Call this method after batch insertion is completed, and only if startIndexing() 110 /// was called before batch insertion was started. 111 Q_INVOKABLE void endIndexing(); 112 113 /// Helper class to automatically call startIndexing and endIndexing. 114 /// Its constructor calls startIndexing and its destructor calls endIndexing. 115 /// 116 /// Example: 117 /// ... 118 /// { 119 /// ctkDICOMIndexer::ScopedIndexing indexingBatch(indexer, database); // this calls startIndexing 120 /// indexer.addDirectory(database, dir1); 121 /// indexer.addDirectory(database, dir2); 122 /// indexer.addDirectory(database, dir3); 123 /// } // endIndexing is called when indexingBatch goes out of scope 124 /// 125 class ScopedIndexing 126 { 127 public: ScopedIndexing(ctkDICOMIndexer & indexer,ctkDICOMDatabase & database)128 ScopedIndexing(ctkDICOMIndexer& indexer, ctkDICOMDatabase& database) 129 { 130 this->Indexer = &indexer; 131 this->Indexer->startIndexing(database); 132 } ~ScopedIndexing()133 ~ScopedIndexing() 134 { 135 this->Indexer->endIndexing(); 136 } 137 private: 138 ctkDICOMIndexer* Indexer; 139 }; 140 141 Q_SIGNALS: 142 void foundFilesToIndex(int); 143 void indexingFileNumber(int); 144 void indexingFilePath(QString); 145 void progress(int); 146 void indexingComplete(); 147 148 public Q_SLOTS: 149 void cancel(); 150 151 protected: 152 QScopedPointer<ctkDICOMIndexerPrivate> d_ptr; 153 154 private: 155 Q_DECLARE_PRIVATE(ctkDICOMIndexer); 156 Q_DISABLE_COPY(ctkDICOMIndexer); 157 158 }; 159 160 #endif 161