diff --git a/CMakeLists.txt b/CMakeLists.txt index 198ca1e809..46e7aa7687 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,8 @@ cmake_minimum_required(VERSION 3.19) +set(QT_VERSION_MAJOR 5) + if(POLICY CMP0020) cmake_policy(SET CMP0020 NEW) endif() diff --git a/packaging/windows/WindowsPackaging.cmake b/packaging/windows/WindowsPackaging.cmake index 351139faaf..a4cf5a5adb 100644 --- a/packaging/windows/WindowsPackaging.cmake +++ b/packaging/windows/WindowsPackaging.cmake @@ -96,8 +96,11 @@ set(CONFIG_MODE $<$:Debug>$<$:Release>$<$ +#include +#include +#include + +class medFirstStartPrivate +{ +public: + medFirstStartPrivate() = default; + ~medFirstStartPrivate() = default; + + /** + * @struct st_fileInfoUpdate + * @brief Internal structure to store information about a file to check and update. + */ + struct st_fileInfoUpdate + { + QString pathToCheck; + QString pathRessourceBase; + QString featureName; + QString fileName; + QString urlDL; + std::function init; + std::function update; + }; + + /** + * @brief List of files to check install or update. + */ + QVector listFilesToCheckAndUpdate; + QNetworkAccessManager *qnam; + +}; + +class medUpdateReferencesFilesThread : public QRunnable +{ +public: + medUpdateReferencesFilesThread(medFirstStart * parent) : m_parent(parent) {}; + virtual ~medUpdateReferencesFilesThread() = default; + + void run() override + { + m_parent->updates(); + } + + medFirstStart * m_parent; +}; + +medFirstStart::medFirstStart(QNetworkAccessManager *qnam) +{ + d = new medFirstStartPrivate(); + d->qnam = qnam; +} + +medFirstStart::~medFirstStart() +{ + delete d; +} + + + + +void medFirstStart::pushPathToCheck(QString pathToCheck, QString pathRessourceBase, QString featureName, QString url, std::function init, std::function update) +{ + d->listFilesToCheckAndUpdate.push_back({ pathToCheck, pathRessourceBase, featureName, QFileInfo(pathToCheck).fileName(), url, init, update }); +} + +void medFirstStart::checkAndUpdate() +{ + checks(); + medUpdateReferencesFilesThread * updateThread = new medUpdateReferencesFilesThread(this); + QThreadPool::globalInstance()->start(updateThread); +} + +void medFirstStart::checks() +{ + for (auto & fileToCheckAndUpdate : d->listFilesToCheckAndUpdate) + { + medFirstStartUpdateFile fileUpdater(fileToCheckAndUpdate.pathToCheck, fileToCheckAndUpdate.featureName, fileToCheckAndUpdate.pathRessourceBase, fileToCheckAndUpdate.update, fileToCheckAndUpdate.init); + fileUpdater.installFile(); + } +} + +void medFirstStart::updates() +{ + for (auto & fileToCheckAndUpdate : d->listFilesToCheckAndUpdate) + { + medFirstStartClient fileClientDL(fileToCheckAndUpdate.featureName, fileToCheckAndUpdate.fileName, fileToCheckAndUpdate.urlDL, d->qnam); + fileClientDL.updateReferenceFile(); + } +} diff --git a/src/app/medInria/FirstStart/medFirstStart.h b/src/app/medInria/FirstStart/medFirstStart.h new file mode 100644 index 0000000000..4af0dc9a31 --- /dev/null +++ b/src/app/medInria/FirstStart/medFirstStart.h @@ -0,0 +1,85 @@ +#pragma once +/*========================================================================= + + medInria + + Copyright (c) INRIA 2013 - 2020. All rights reserved. + See LICENSE.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + +=========================================================================*/ + +/** + * @file medFirstStart.h + * @brief Header file for the medFirstStart class. + * @copyright Copyright (c) INRIA 2013 - 2020. All rights reserved. + * @see LICENSE.txt for details. + * + * This software is distributed WITHOUT ANY WARRANTY; without even + * the   + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. + */ +#include +#include +#include + +#include + + /** + * @brief Private class for medFirstStart. + */ +class medFirstStartPrivate; + +class QNetworkAccessManager; + +/** + * @class medFirstStart + * @brief This class provides functionalities to setup or update configuration files for another application. + */ +class medFirstStart : public QObject +{ + Q_OBJECT +public: + /** + * @brief Default constructor. + */ + medFirstStart(QNetworkAccessManager *qnam); + + /** + * @brief Destructor. + */ + ~medFirstStart(); + + /** + * @brief Pushes a path to check for updates to the internal list. + * + * @param pathToCheck Path to the file to check for updates. + * @param pathRessourceBase Base path for the resource. + * @param featureName Name of the feature associated with the file. + * @param fileName Name of the file. + * @param url Optional URL for downloading new version for the reference file. + * @param init Optional callback function to initialize the file. + * @param update Optional callback function to update the file. + */ + void pushPathToCheck(QString pathToCheck, QString pathRessourceBase, + QString featureName, //QString fileName, + QString url = "", + std::function init = nullptr, + std::function update = nullptr); + + /** + * @brief Checks and updates all files added with pushPathToCheck. + */ + void checkAndUpdate(); + + void checks(); + void updates(); + +private: + medFirstStartPrivate *d; +}; + diff --git a/src/app/medInria/FirstStart/medFirstStartClient.cpp b/src/app/medInria/FirstStart/medFirstStartClient.cpp new file mode 100644 index 0000000000..100a190e09 --- /dev/null +++ b/src/app/medInria/FirstStart/medFirstStartClient.cpp @@ -0,0 +1,104 @@ +/*========================================================================= + + medInria + + Copyright (c) INRIA 2013 - 2020. All rights reserved. + See LICENSE.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + +=========================================================================*/ + +#include + +#include "medFirstStartDownloader.h" +#include "medFirstStartCommon.h" + +#include +#include +#include +#include + +class medFirstStartClientPrivate : public QObject +{ +public: + medFirstStartClientPrivate(QNetworkAccessManager *qnam) : dl(qnam){}; + ~medFirstStartClientPrivate() = default; + + QString uri; + QString updateDirPath; + QString lastDirPath; + QString lastFilePath; + QString tmpDirPath; + QString tmpFilePath; + + medFirstStartDownloader dl; +}; + +medFirstStartClient::medFirstStartClient(QString featureName, QString fileName, QString uri, QNetworkAccessManager *qnam) +{ + d = new medFirstStartClientPrivate(qnam); + + QString baseUpdatedPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/" + QCoreApplication::organizationName() + "/" + QCoreApplication::applicationName() + "/resources/conf/"; + + d->uri = uri; + d->updateDirPath = baseUpdatedPath + featureName; + d->lastDirPath = d->updateDirPath + "/last/"; + d->lastFilePath = d->lastDirPath + fileName; + d->tmpDirPath = d->updateDirPath + "/tmp/"; + d->tmpFilePath = d->tmpDirPath + fileName; +} + +medFirstStartClient::~medFirstStartClient() +{ + delete d; +} + + +bool medFirstStartClient::updateReferenceFile() +{ + bool bRes = true; + + if (!d->uri.isEmpty()) + { + QDir(d->updateDirPath).mkpath("."); + QDir(d->tmpDirPath).mkpath("."); + if (d->dl.download(d->uri, d->tmpFilePath)) + { + if (!medFirstStartCommon::comparerFiles(d->lastFilePath, d->tmpFilePath)) + { + if (QFile::exists(d->lastDirPath)) + { + QDir(d->updateDirPath).rename("last", getNextArchiveFolderName()); + } + QDir(d->tmpDirPath).rename(d->tmpDirPath, d->lastDirPath); + } + } + else + { + bRes = false; + } + } + + return bRes; +} + +QString medFirstStartClient::getNextArchiveFolderName() +{ + int iMax = 0; + QDir updateDir(d->updateDirPath); + auto subDirs = updateDir.entryList(QDir::NoDotAndDotDot & QDir::Dirs); + for (auto subDir : subDirs) + { + bool ok; + int i = subDir.toInt(&ok); + if (ok) + { + iMax = std::max(iMax, i); + } + } + + return QString::number(iMax + 1); +} diff --git a/src/app/medInria/FirstStart/medFirstStartClient.h b/src/app/medInria/FirstStart/medFirstStartClient.h new file mode 100644 index 0000000000..ab339df64a --- /dev/null +++ b/src/app/medInria/FirstStart/medFirstStartClient.h @@ -0,0 +1,35 @@ +#pragma once +/*========================================================================= + + medInria + + Copyright (c) INRIA 2013 - 2020. All rights reserved. + See LICENSE.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + +=========================================================================*/ + +#include +#include +#include + +class QNetworkAccessManager; +class medFirstStartClientPrivate; +class medFirstStartClient : public QObject +{ +public: + medFirstStartClient(QString featureName, QString fileName, QString uri, QNetworkAccessManager *qnam); + ~medFirstStartClient(); + + bool updateReferenceFile (); + +private: + QString getNextArchiveFolderName(); + +private: + medFirstStartClientPrivate *d; +}; + diff --git a/src/app/medInria/FirstStart/medFirstStartCommon.cpp b/src/app/medInria/FirstStart/medFirstStartCommon.cpp new file mode 100644 index 0000000000..cdbfb76433 --- /dev/null +++ b/src/app/medInria/FirstStart/medFirstStartCommon.cpp @@ -0,0 +1,98 @@ +/*========================================================================= + + medInria + + Copyright (c) INRIA 2013 - 2020. All rights reserved. + See LICENSE.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + +=========================================================================*/ + +#include "medFirstStartCommon.h" + +#include +#include +#include +#include + +/** + * @brief Compares two files to see if their content is identical. + * + * @param path1 Path to the first file. + * @param path2 Path to the second file. + * @return True if the files have the same content, false otherwise. + */ +bool medFirstStartCommon::comparerFiles(const QString & path1, const QString & path2) +{ + // Ouvrir les deux fichiers en lecture binaire + QFile file1(path1); + QFile file2(path2); + + if (!file1.open(QIODevice::ReadOnly) || !file2.open(QIODevice::ReadOnly)) + { + return false; // Si l'ouverture d'un des fichiers échoue, les fichiers sont considérés comme différents + } + + // Comparer les fichiers bloc par bloc + QByteArray block1, block2; + block1 = file1.readAll(); + block2 = file2.readAll(); + + return block1 == block2; +} + + +/** + * @brief Copies a file from source to destination. + * + * @param pathSource Path to the source file. + * @param pathDest Path to the destination file. + * @return True if the copy was successful, false otherwise. + */ +bool medFirstStartCommon::copy(QString const & pathSource, QString const & pathDest) +{ + bool bRes = true; + + QFileInfo fiSource(pathSource); + if (fiSource.isFile()) + { + QDir destDir = QFileInfo(pathDest).dir(); + destDir.mkpath(destDir.absolutePath()); + QFile::remove(pathDest); + bRes = QFile::copy(pathSource, pathDest); + } + else if (fiSource.isDir()) + { + QDirIterator it(pathSource, QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + QDir dir(pathSource); + const int srcPathLength = dir.canonicalPath().length(); + + while (it.hasNext()) + { + it.next(); + + const auto fi = it.fileInfo(); + const QString relPath = fi.canonicalPath().mid(srcPathLength); + const QString absDstPath = pathDest + relPath; + + if (fi.isFile()) + { + QFile::remove(absDstPath); + bRes = bRes && QFile::copy(fi.canonicalPath(), absDstPath); + } + else if (fi.isDir()) + { + bRes = bRes && dir.mkpath(absDstPath); + } + } + } + else + { + bRes = false; + } + + return bRes; +} diff --git a/src/app/medInria/FirstStart/medFirstStartCommon.h b/src/app/medInria/FirstStart/medFirstStartCommon.h new file mode 100644 index 0000000000..23e964ee1f --- /dev/null +++ b/src/app/medInria/FirstStart/medFirstStartCommon.h @@ -0,0 +1,22 @@ +#pragma once +/*========================================================================= + + medInria + + Copyright (c) INRIA 2013 - 2020. All rights reserved. + See LICENSE.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + +=========================================================================*/ + +#include + +namespace medFirstStartCommon +{ + bool comparerFiles(const QString & path1, const QString & path2); + bool copy(QString const & pathSource, QString const & pathDest); +}; + diff --git a/src/app/medInria/FirstStart/medFirstStartDownloader.cpp b/src/app/medInria/FirstStart/medFirstStartDownloader.cpp new file mode 100644 index 0000000000..4531f4eb51 --- /dev/null +++ b/src/app/medInria/FirstStart/medFirstStartDownloader.cpp @@ -0,0 +1,115 @@ +/*========================================================================= + + medInria + + Copyright (c) INRIA 2013 - 2020. All rights reserved. + See LICENSE.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + +=========================================================================*/ + +#include "medFirstStartDownloader.h" + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +class medFirstStartDownloaderPrivate +{ +public: + medFirstStartDownloaderPrivate() = default; + ~medFirstStartDownloaderPrivate() = default; + + QMap replyWaiterMap; + QMap replyPathMap; + QNetworkAccessManager * qnam; +}; + +medFirstStartDownloader::medFirstStartDownloader(QNetworkAccessManager * qnam) +{ + d = new medFirstStartDownloaderPrivate(); + d->qnam = qnam; +} + +medFirstStartDownloader::~medFirstStartDownloader() +{ + delete d; +} + + + +bool medFirstStartDownloader::download(QString url, QString path) +{ + bool bRes = false; + + if (!url.isEmpty() && !path.isEmpty()) + { + QNetworkRequest request(url); + request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + QNetworkReply * reply = d->qnam->get(request); + + // Connecting the request manager slots to the signals sent by the reply object + QObject::connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(slotDownloadProgress(qint64, qint64))); + QObject::connect(reply, SIGNAL(finished()), this, SLOT(slotFinished())); + QObject::connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(slotError(QNetworkReply::NetworkError))); + + QEventLoop *waiter = new QEventLoop(nullptr);/* Create the QEventLoop */ + d->replyWaiterMap[reply] = waiter; + d->replyPathMap[reply] = path; + bRes = waiter->exec() == 0;/* Execute the QEventLoop - it will quit when the above finished due to the connect() */ + + if (bRes) + { + auto payload = reply->readAll(); + QFile outputFile(path); + outputFile.open(QFile::WriteOnly | QFile::Truncate); + bRes = outputFile.write(payload) == payload.size(); + } + else + { + int httpCode = static_cast(reply->error()); + } + } + + return bRes; +} + + + +//-------------------------------------------------------------------------------------------------------------------------- + +void medFirstStartDownloader::slotError(QNetworkReply::NetworkError err) +{ + QNetworkReply *reply = dynamic_cast(QObject::sender()); // retrieving the reply object who sent an error signal + if (reply) //handling the reply error information + { + d->replyWaiterMap[reply]->exit(-1); + } +} + +void medFirstStartDownloader::slotDownloadProgress(qint64 bytesSent, qint64 bytesTotal) +{ + QNetworkReply *reply = dynamic_cast(QObject::sender()); // retrieving the reply object who sent a download signal + //TODO Log +} + +void medFirstStartDownloader::slotFinished() +{ + QNetworkReply *reply = dynamic_cast(QObject::sender()); // retrieving the reply object who sent a finish signal + if (reply) //handling the reply finish information + { + d->replyWaiterMap[reply]->exit(0); + } +} + diff --git a/src/app/medInria/FirstStart/medFirstStartDownloader.h b/src/app/medInria/FirstStart/medFirstStartDownloader.h new file mode 100644 index 0000000000..fd4930711c --- /dev/null +++ b/src/app/medInria/FirstStart/medFirstStartDownloader.h @@ -0,0 +1,38 @@ +#pragma once +/*========================================================================= + + medInria + + Copyright (c) INRIA 2013 - 2020. All rights reserved. + See LICENSE.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + +=========================================================================*/ + +#include +#include +#include + +class QNetworkAccessManager; + +class medFirstStartDownloaderPrivate; +class medFirstStartDownloader : public QObject +{ + Q_OBJECT +public: + medFirstStartDownloader(QNetworkAccessManager * qnam); + ~medFirstStartDownloader(); + + bool download(QString url, QString path); + +private slots: + void slotError(QNetworkReply::NetworkError err); + void slotDownloadProgress(qint64 bytesSent, qint64 bytesTotal); + void slotFinished(); + +private: + medFirstStartDownloaderPrivate *d; +}; diff --git a/src/app/medInria/FirstStart/medFirstStartUpdateFile.cpp b/src/app/medInria/FirstStart/medFirstStartUpdateFile.cpp new file mode 100644 index 0000000000..ffff22ee68 --- /dev/null +++ b/src/app/medInria/FirstStart/medFirstStartUpdateFile.cpp @@ -0,0 +1,133 @@ +/*========================================================================= + + medInria + + Copyright (c) INRIA 2013 - 2020. All rights reserved. + See LICENSE.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + +=========================================================================*/ + +#include "medFirstStartUpdateFile.h" + +#include "medFirstStartCommon.h" + +#include +#include +#include +#include +#include +#include + + +class medFirstStartUpdateFilePrivate +{ +public: + medFirstStartUpdateFilePrivate() = default; + ~medFirstStartUpdateFilePrivate() = default; + + + QString fileName; + + QString updateDirPath; + QString lastFilePath; + QString filePath; + QString originalFilePath; + + std::function update; + std::function init; +}; + +medFirstStartUpdateFile::medFirstStartUpdateFile(QString filePath, QString featureName, QString originalFilePath, + std::function update, std::function init) +{ + d = new medFirstStartUpdateFilePrivate(); + QString baseUpdatedPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/" + QCoreApplication::organizationName() + "/" + QCoreApplication::applicationName() + "/resources/conf/"; + + d->update = update; + d->init = init; + + d->fileName = QFileInfo(filePath).fileName(); + d->updateDirPath = baseUpdatedPath + featureName; + d->lastFilePath = d->updateDirPath + "/last/" + d->fileName; + d->filePath = filePath; + d->originalFilePath = originalFilePath; +} + +medFirstStartUpdateFile::~medFirstStartUpdateFile() +{ + delete d; +} + + + + +bool medFirstStartUpdateFile::installFile() +{ + bool bRes = prepareFile(); + + if (curentFileOutdated()) + { + if (d->init) + { + d->init(d->lastFilePath, d->filePath); + } + + if (d->update) + { + d->update(d->lastFilePath, d->filePath); + } + bRes = medFirstStartCommon::copy(d->lastFilePath, d->filePath); + } + + return bRes; +} + +bool medFirstStartUpdateFile::prepareFile() +{ + bool bRes = true; + + QDir(d->updateDirPath).mkpath("."); + + if (!QFile::exists(d->lastFilePath)) + { + bRes = medFirstStartCommon::copy(d->originalFilePath, d->lastFilePath); + } + + return bRes; +} + +bool medFirstStartUpdateFile::curentFileOutdated() +{ + bool bRes = false; + + QDir updateDir(d->updateDirPath); + + if (updateDir.exists()) + { + if (QFile::exists(d->filePath)) + { + if (!medFirstStartCommon::comparerFiles(d->lastFilePath, d->filePath)) + { + auto subDirs = updateDir.entryList(QDir::NoDotAndDotDot | QDir::AllDirs); + for (auto subDir : subDirs) + { + bRes |= medFirstStartCommon::comparerFiles(d->filePath, d->updateDirPath + '/' + subDir + '/' + d->fileName); + } + } + } + else + { + bRes = true; + } + } + else + { + bRes = true; + } + + return bRes; +} diff --git a/src/app/medInria/FirstStart/medFirstStartUpdateFile.h b/src/app/medInria/FirstStart/medFirstStartUpdateFile.h new file mode 100644 index 0000000000..fe83d743e6 --- /dev/null +++ b/src/app/medInria/FirstStart/medFirstStartUpdateFile.h @@ -0,0 +1,37 @@ +#pragma once +/*========================================================================= + + medInria + + Copyright (c) INRIA 2013 - 2020. All rights reserved. + See LICENSE.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. + +=========================================================================*/ + +#include +#include + +#include + +class medFirstStartUpdateFilePrivate; +class medFirstStartUpdateFile : public QObject +{ +public: + medFirstStartUpdateFile(QString filePath, QString featureName, QString originalFilePath, + std::function update = nullptr, std::function init = nullptr); + ~medFirstStartUpdateFile(); + + bool installFile(); + +private: + bool prepareFile(); + bool curentFileOutdated(); + +private: + medFirstStartUpdateFilePrivate *d; +}; + diff --git a/src/app/medInria/areas/homepage/medHomepageArea.cpp b/src/app/medInria/areas/homepage/medHomepageArea.cpp index 475b52cd55..9b9e68777c 100644 --- a/src/app/medInria/areas/homepage/medHomepageArea.cpp +++ b/src/app/medInria/areas/homepage/medHomepageArea.cpp @@ -9,7 +9,7 @@ * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ -#include +#include #include #include #include @@ -17,6 +17,8 @@ #include #include +#include + class medHomepageAreaPrivate { public: @@ -75,7 +77,11 @@ void medHomepageArea::resizeEvent ( QResizeEvent * event ) d->navigationWidget->setProperty("pos", QPoint(20, height()/4)); // The description text is resized when the window is resized - QPixmap pixmap = d->applicationLabel->pixmap(Qt::ReturnByValue); +#if QT_VERSION < 0x060000 + QPixmap pixmap = *d->applicationLabel->pixmap(); +#else + QPixmap pixmap = d->applicationLabel->pixmap(); +#endif d->descriptionWidget->resize(width() - 20, pixmap.height()); } diff --git a/src/app/medInria/main.cpp b/src/app/medInria/main.cpp index 3287996980..daab858f67 100644 --- a/src/app/medInria/main.cpp +++ b/src/app/medInria/main.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef WIN32 #include @@ -40,6 +41,8 @@ #include +#include + void forceShow(medMainWindow &mainwindow) { // Idea and code taken from the OpenCOR project, Thanks Allan for the code! @@ -82,8 +85,7 @@ void forceShow(medMainWindow &mainwindow) int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - // Setup openGL surface compatible with QVTKOpenGLWidget, - // required by medVtkView + // Setup openGL surface compatible with QVTKOpenGLWidget, required by medVtkView QSurfaceFormat fmt; fmt.setRenderableType(QSurfaceFormat::OpenGL); fmt.setVersion(3, 2); @@ -113,7 +115,6 @@ int main(int argc, char *argv[]) {"no-fullscreen", QCoreApplication::translate("main", "Open application in windowed mode")}, {"stereo", QCoreApplication::translate("main", "Open application in opengl direct rendering")}, {"debug", QCoreApplication::translate("main", "Open application in debug mode")}, - {{"remotedb", "psql"}, QCoreApplication::translate("main", "Connect application to a remote database controller (psql)")}, // Options with a value #ifdef ACTIVATE_WALL_OPTION {{"wall", "tracker" @@ -126,221 +127,187 @@ int main(int argc, char *argv[]) {{"r", "role"}, QCoreApplication::translate("main", "Open database with defined role ."), QCoreApplication::translate("main", "junior/expert/coordinateur")}, - {{"c", "center"}, - QCoreApplication::translate("main", "Open database for a specific center
."), - QCoreApplication::translate("main", "center")}, - {"host", - QCoreApplication::translate("main", "database server host or socket directory (default: \"local socket\"). \nThis parameter is taken into account only when remotedb parameter is defined"), - QCoreApplication::translate("main", "HOSTNAME")}, - {{"port","p"}, - QCoreApplication::translate("main", "database server port (default: \"5432\"). \nThis parameter is taken into account only when remotedb parameter is defined"), - QCoreApplication::translate("main", "PORT")}, - {"db_prefix_path", - QCoreApplication::translate("main", "set database prefix path. \nThis parameter is taken into account only when remotedb parameter is defined"), - QCoreApplication::translate("main", "")}, }); - // Process the actual command line arguments given by the user - parser.process(application); - - if (parser.isSet("center")) + // Process the actual command line arguments given by the user + parser.process(application); + + if (parser.isSet("center")) + { + int center = parser.value("center").toInt(); + medSettingsManager *mnger = medSettingsManager::instance(); + mnger->setValue("database", "center", center, false); + } + + const bool remoteDb = parser.isSet("remotedb"); + if (remoteDb) + { + medSettingsManager *mnger = medSettingsManager::instance(); + mnger->setValue("database", "remotedb", remoteDb, false); + if (parser.isSet("host")) { - int center = parser.value("center").toInt(); - medSettingsManager *mnger = medSettingsManager::instance(); - mnger->setValue("database", "center", center, false); + QString hostname = parser.value("host"); + mnger->setValue("database", "hostname", hostname, false); } - - const bool remoteDb = parser.isSet("remotedb"); - if (remoteDb) + if (parser.isSet("port")) { - medSettingsManager *mnger = medSettingsManager::instance(); - mnger->setValue("database", "remotedb", remoteDb, false); - if (parser.isSet("host")) - { - QString hostname = parser.value("host"); - mnger->setValue("database", "hostname", hostname, false); - } - if (parser.isSet("port")) - { - int port = parser.value("port").toInt(); - mnger->setValue("database", "port", port, false); - } - if (parser.isSet("db_prefix_path")) - { - QString db_prefix_path = parser.value("db_prefix_path"); - mnger->setValue("database", "db_prefix_path", db_prefix_path, false); - } + int port = parser.value("port").toInt(); + mnger->setValue("database", "port", port, false); } - const bool DirectView = parser.isSet("view"); - QStringList viewPaths = parser.values("view"); - - // const bool DirectView = - // dtkApplicationArgumentsContain(&application,"--view") || - // posargs.size()!=0; - int runningMedInria = 0; - if (DirectView) + if (parser.isSet("db_prefix_path")) { - for (QStringList::const_iterator i = viewPaths.constBegin(); - i != viewPaths.constEnd(); ++i) - { - const QString &message = QString("/open ") + *i; - runningMedInria = application.sendMessage(message); - } + QString db_prefix_path = parser.value("db_prefix_path"); + mnger->setValue("database", "db_prefix_path", db_prefix_path, false); } - else + } + const bool DirectView = parser.isSet("view"); + QStringList viewPaths = parser.values("view"); + + + int runningMedInria = 0; + if (DirectView) + { + for (QStringList::const_iterator i = viewPaths.constBegin(); i != viewPaths.constEnd(); ++i) { - runningMedInria = application.sendMessage(""); + const QString &message = QString("/open ") + *i; + runningMedInria = application.sendMessage(message); } - if (runningMedInria) - return 0; - - //auto testWindow = new QMainWindow(); - //auto w = new medSpoilerWidget(); - //QHBoxLayout * lay1 = new QHBoxLayout(); - //QVBoxLayout * lay2 = new QVBoxLayout(); - //lay2->addWidget(new QPushButton("TATA BUTTON")); - //lay2->addWidget(new QPushButton("TOTO BUTTON")); - //w->setContentLayout(*lay2); - //testWindow->setCentralWidget(w); - //testWindow->show(); - // - // - //const int status1 = application.exec(); - //return status1; - - medSourcesLoader::instance(&application); - - medPluginManager::instance()->setVerboseLoading(true); - medPluginManager::instance()->initialize(); - auto sourceHandler = medSourceHandler::instance(&application); - auto model = medDataHub::instance(&application); - auto virtualRepresentation = new medVirtualRepresentation(&application); - auto toto1 = QObject::connect(medSourcesLoader::instance(), SIGNAL(sourceAdded(medAbstractSource *)), sourceHandler, SLOT(addSource(medAbstractSource *))); - auto toto2 = QObject::connect(medSourcesLoader::instance(), SIGNAL(sourceRemoved(medAbstractSource *)), sourceHandler, SLOT(removeSource(medAbstractSource *))); - auto toto3 = QObject::connect(medSourcesLoader::instance(), &medSourcesLoader::defaultWorkingSource, sourceHandler, &medSourceHandler::setDefaultWorkingSource); - model->setVirtualRepresentation(virtualRepresentation); - - medSourcesLoader::instance()->loadFromDisk(); - - - auto notifSys = medNotifSys::instance(); + } + else + { + runningMedInria = application.sendMessage(""); + } + if (runningMedInria) + return 0; + + + QNetworkAccessManager *qnam = new QNetworkAccessManager(&application); + medFirstStart firstStart(qnam); + firstStart.pushPathToCheck(medSourcesLoader::path(), ":/configs/DataSourcesDefault.json", "dataSourceLoader", "", medSourcesLoader::initSourceLoaderCfg); + firstStart.checkAndUpdate(); + + + medSourcesLoader::instance(&application); + + medPluginManager::instance()->setVerboseLoading(true); + medPluginManager::instance()->initialize(); + auto sourceHandler = medSourceHandler::instance(&application); + auto model = medDataHub::instance(&application); + auto virtualRepresentation = new medVirtualRepresentation(&application); + QObject::connect(medSourcesLoader::instance(), SIGNAL(sourceAdded(medAbstractSource *)), sourceHandler, SLOT(addSource(medAbstractSource *))); + QObject::connect(medSourcesLoader::instance(), SIGNAL(sourceRemoved(medAbstractSource *)), sourceHandler, SLOT(removeSource(medAbstractSource *))); + QObject::connect(medSourcesLoader::instance(), &medSourcesLoader::defaultWorkingSource, sourceHandler, &medSourceHandler::setDefaultWorkingSource); + model->setVirtualRepresentation(virtualRepresentation); + + medSourcesLoader::instance()->loadFromDisk(); + + auto notifSys = medNotifSys::instance(); - medApplicationContext::instance()->setParent(&application); - medApplicationContext::instance()->setVirtualRepresentation(virtualRepresentation); - medApplicationContext::instance()->setDataHub(model); - medApplicationContext::instance()->setNotifSys(notifSys); - medApplicationContext::instance()->setSourceHandler(sourceHandler); - medApplicationContext::instance()->setPluginManager(medPluginManager::instance()); - medApplicationContext::instance()->setDataManager(medDataManager::instance()); - - - //medMainWindow *mainwindow2 = new medMainWindow; - - - //auto status2 = new QStatusBar(mainwindow2); - //status2->setContentsMargins(0, 0, 0, 0); - //mainwindow2->setStatusBar(status2); - //auto stBarW = medNotifSysPresenter(notifSys).buildWidgetForStatusBar(); - //status2->addPermanentWidget(stBarW); - //mainwindow2->show(); - //status2->show(); - //stBarW->show(); - - notifSys->setOperatingSystemNotification(true); - notifSys->setOperatingSystemNotification(true); - notifSys->setOSNotifOnlyNonFocus(true); - QObject::connect(&application, &QGuiApplication::focusWindowChanged, - [=](QWindow *focusWindow) - { - notifSys->windowOnTop(focusWindow != nullptr); - } - ); - - - - // Use Qt::WA_DeleteOnClose attribute to be sure to always have only one - // closeEvent. - medMainWindow *mainwindow = new medMainWindow; - - auto notifBanner = static_cast(medNotifSysPresenter(notifSys).buildNotificationWindow()); - notifBanner->setParent(mainwindow); - QObject::connect(mainwindow->notifButton(), &QToolButton::clicked, notifBanner, &medNotificationPaneWidget::switchVisibility); - - mainwindow->setAttribute(Qt::WA_DeleteOnClose, true); - - if (DirectView) - mainwindow->setStartup(medMainWindow::WorkSpace, viewPaths); - - bool fullScreen = medSettingsManager::instance() - ->value("startup", "fullscreen", false) - .toBool(); - const bool hasFullScreenArg = parser.isSet("fullscreen"); - const bool hasNoFullScreenArg = parser.isSet("no-fullscreen"); - const bool hasWallArg = false; + medApplicationContext::instance()->setParent(&application); + medApplicationContext::instance()->setVirtualRepresentation(virtualRepresentation); + medApplicationContext::instance()->setDataHub(model); + medApplicationContext::instance()->setNotifSys(notifSys); + medApplicationContext::instance()->setSourceHandler(sourceHandler); + medApplicationContext::instance()->setPluginManager(medPluginManager::instance()); + medApplicationContext::instance()->setDataManager(medDataManager::instance()); + + notifSys->setOperatingSystemNotification(true); + notifSys->setOperatingSystemNotification(true); + notifSys->setOSNotifOnlyNonFocus(true); + QObject::connect(&application, &QGuiApplication::focusWindowChanged, + [=](QWindow *focusWindow) + { + notifSys->windowOnTop(focusWindow != nullptr); + } + ); + + + + // Use Qt::WA_DeleteOnClose attribute to be sure to always have only one + // closeEvent. + medMainWindow *mainwindow = new medMainWindow; + + auto notifBanner = static_cast(medNotifSysPresenter(notifSys).buildNotificationWindow()); + notifBanner->setParent(mainwindow); + + QObject::connect(mainwindow->notifButton(), &QToolButton::clicked, notifBanner, &medNotificationPaneWidget::switchVisibility); + + mainwindow->setAttribute(Qt::WA_DeleteOnClose, true); + + if (DirectView) + mainwindow->setStartup(medMainWindow::WorkSpace, viewPaths); + + bool fullScreen = medSettingsManager::instance()->value("startup", "fullscreen", false).toBool(); + + const bool hasFullScreenArg = parser.isSet("fullscreen"); + const bool hasNoFullScreenArg = parser.isSet("no-fullscreen"); + const bool hasWallArg = false; #ifdef ACTIVATE_WALL_OPTION - hasWallArg = parser.isSet("wall"); + hasWallArg = parser.isSet("wall"); #endif - const int conflict = static_cast(hasFullScreenArg) + - static_cast(hasNoFullScreenArg) + - static_cast(hasWallArg); - - if (conflict > 1) - dtkWarn() << "Conflicting command line parameters between " - "--fullscreen, --no-fullscreen and -wall. Ignoring."; - else + const int conflict = static_cast(hasFullScreenArg) + + static_cast(hasNoFullScreenArg) + + static_cast(hasWallArg); + + if (conflict > 1) + { + dtkWarn() << "Conflicting command line parameters between " "--fullscreen, --no-fullscreen and -wall. Ignoring."; + } + else + { + if (hasWallArg) { - if (hasWallArg) - { - mainwindow->setWallScreen(true); - fullScreen = false; - } + mainwindow->setWallScreen(true); + fullScreen = false; + } - if (hasFullScreenArg) - fullScreen = true; + if (hasFullScreenArg) + fullScreen = true; - if (hasNoFullScreenArg) - fullScreen = false; - } + if (hasNoFullScreenArg) + fullScreen = false; + } - mainwindow->setFullScreen(fullScreen); + mainwindow->setFullScreen(fullScreen); #ifdef WIN32 - QWindowsWindowFunctions::setHasBorderInFullScreen(mainwindow->windowHandle(), true); + QWindowsWindowFunctions::setHasBorderInFullScreen(mainwindow->windowHandle(), true); #endif - if (parser.isSet("stereo")) - { - QGLFormat format; - format.setAlpha(true); - format.setDoubleBuffer(true); - format.setStereo(true); - format.setDirectRendering(true); - QGLFormat::setDefaultFormat(format); - } + if (parser.isSet("stereo")) + { + QGLFormat format; + format.setAlpha(true); + format.setDoubleBuffer(true); + format.setStereo(true); + format.setDirectRendering(true); + QGLFormat::setDefaultFormat(format); + } - if (medPluginManager::instance()->plugins().isEmpty()) - { - QMessageBox::warning( - mainwindow, QObject::tr("No plugin loaded"), - QObject::tr("Warning : no plugin loaded successfully.")); - } - // Handle file associations open requests that were not handled in the - // application - QObject::connect(&application, SIGNAL(messageReceived(const QString &)), - mainwindow, - SLOT(processNewInstanceMessage(const QString &))); + if (medPluginManager::instance()->plugins().isEmpty()) + { + QMessageBox::warning( + mainwindow, QObject::tr("No plugin loaded"), + QObject::tr("Warning : no plugin loaded successfully.")); + } + + // Handle file associations open requests that were not handled in the + // application + QObject::connect(&application, SIGNAL(messageReceived(const QString &)), + mainwindow, + SLOT(processNewInstanceMessage(const QString &))); - application.setMainWindow(mainwindow); + application.setMainWindow(mainwindow); - forceShow(*mainwindow); + forceShow(*mainwindow); - qInfo() << "### Application is running..."; + qInfo() << "### Application is running..."; - // Start main loop. - const int status = application.exec(); + // Start main loop. + const int status = application.exec(); - medPluginManager::instance()->uninitialize(); + medPluginManager::instance()->uninitialize(); - return status; + return status; } diff --git a/src/app/medInria/medApplication.cpp b/src/app/medInria/medApplication.cpp index dbe23dd447..86a32d3f92 100644 --- a/src/app/medInria/medApplication.cpp +++ b/src/app/medInria/medApplication.cpp @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/src/app/medInria/medApplication.h b/src/app/medInria/medApplication.h index 3cab5a240b..352ca681c4 100644 --- a/src/app/medInria/medApplication.h +++ b/src/app/medInria/medApplication.h @@ -13,14 +13,13 @@ =========================================================================*/ #include -//#include #include #include "QSingleApplication/qtlocalpeer.h" class medApplicationPrivate; class medMainWindow; -class medApplication : public QApplication //QtSingleApplication +class medApplication : public QApplication { Q_OBJECT diff --git a/src/app/medInria/medDataSourceManager.cpp b/src/app/medInria/medDataSourceManager.cpp index 6ff6469d2d..04ed6071b7 100644 --- a/src/app/medInria/medDataSourceManager.cpp +++ b/src/app/medInria/medDataSourceManager.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -87,9 +88,9 @@ void medDataSourceManager::connectDataSource(medAbstractDataSource *dataSource) //TODO: Maybe it is not the best place to put it (medDataManager?) void medDataSourceManager::importData(medAbstractData *data) { - QString patientName = data->metaDataValues(medMetaDataKeys::PatientName.key())[0]; - QString studyName = data->metaDataValues(medMetaDataKeys::StudyDescription.key())[0]; - QString seriesName = data->metaDataValues(medMetaDataKeys::SeriesDescription.key())[0]; + QString patientName = data->metaDataValues(medMetaDataKeys::key("PatientName"))[0]; + QString studyName = data->metaDataValues(medMetaDataKeys::key("StudyDescription"))[0]; + QString seriesName = data->metaDataValues(medMetaDataKeys::key("SeriesDescription"))[0]; QString s_patientName = patientName.simplified(); QString s_studyName = studyName.simplified(); diff --git a/src/app/medInria/medMainWindow.cpp b/src/app/medInria/medMainWindow.cpp index b13c56e14b..ee5f789d72 100644 --- a/src/app/medInria/medMainWindow.cpp +++ b/src/app/medInria/medMainWindow.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include //#include @@ -162,6 +161,7 @@ medMainWindow::medMainWindow ( QWidget *parent ) : QMainWindow ( parent ), d ( n QObject::connect(medApplicationContext::instance()->getApp(), &medApplication::mouseGlobalClick, d->notifWindow, &medNotificationPaneWidget::clicked); initMenuBar(parent); + } medMainWindow::~medMainWindow() @@ -184,6 +184,7 @@ void medMainWindow::initMenuBar(QWidget * parent) menuNotif(menu_bar); menuAbout(menu_bar); + // --- Prepare right corner menu QMenuBar *rightMenuBar = new QMenuBar(menu_bar); menu_bar->setCornerWidget(rightMenuBar); @@ -192,6 +193,7 @@ void medMainWindow::initMenuBar(QWidget * parent) actionNotif->setIcon(QIcon::fromTheme("notifications")); connect(actionNotif, &QAction::triggered, this, &medMainWindow::toggleNotificationPanel); + // --- Fullscreen checkable action QIcon fullscreenIcon; fullscreenIcon.addPixmap(QIcon::fromTheme("fullscreen_off").pixmap(24,24), QIcon::Normal, QIcon::Off); @@ -353,6 +355,7 @@ void medMainWindow::menuSettings(QMenuBar * menu_bar) QMenu *menuSettings = menu_bar->addMenu("Settings"); QAction *actionDataSources = menuSettings->addAction(tr("Data Sources")); + connect(actionDataSources, &QAction::triggered, this, &medMainWindow::onShowDataSources); QAction *actionAreaSettings = menuSettings->addAction(tr("&Startup")); @@ -361,6 +364,7 @@ void medMainWindow::menuSettings(QMenuBar * menu_bar) void medMainWindow::menuAbout(QMenuBar * menu_bar) { + // --- About menu QMenu *menuAbout = menu_bar->addMenu("Help"); @@ -826,6 +830,12 @@ void medMainWindow::filterWSMenu(QString text) } } + + + + + + void medMainWindow::setWallScreen (const bool full ) { if ( full ) @@ -842,7 +852,7 @@ void medMainWindow::setWallScreen (const bool full ) void medMainWindow::setFullScreen (const bool full) { auto fullscreenAction = getCornerAction("Fullscreen"); - if (full) + if ( full ) { setFullscreenOn(fullscreenAction); } @@ -855,7 +865,7 @@ void medMainWindow::setFullScreen (const bool full) void medMainWindow::toggleFullScreen() { auto fullscreenAction = getCornerAction("Fullscreen"); - if (!this->isFullScreen()) + if ( !this->isFullScreen()) { setFullscreenOn(fullscreenAction); } @@ -880,7 +890,7 @@ void medMainWindow::setFullscreenOff(QAction* fullscreenAction) fullscreenAction->blockSignals(true); fullscreenAction->setChecked(false); fullscreenAction->blockSignals(false); - this->showNormal(); + this->showNormal(); } QAction* medMainWindow::getCornerAction(QString actionName) @@ -1237,7 +1247,6 @@ void medMainWindow::closeEvent(QCloseEvent *event) event->accept(); dtkInfo() << "####################################"; - medLogger::finalize(); } diff --git a/src/app/medInria/medMainWindow.h b/src/app/medInria/medMainWindow.h index 229bdb50b2..175d17a8fd 100644 --- a/src/app/medInria/medMainWindow.h +++ b/src/app/medInria/medMainWindow.h @@ -153,11 +153,6 @@ private slots: */ void onShowLicense(); - /** - * @brief Display a database window - */ - // void onShowDatabase(); - /** * @brief Display a settings window for the Area section */ diff --git a/src/app/medInria/medLogger.cpp b/src/app/medInria/old/medLogger.cpp similarity index 100% rename from src/app/medInria/medLogger.cpp rename to src/app/medInria/old/medLogger.cpp diff --git a/src/app/medInria/medLogger.h b/src/app/medInria/old/medLogger.h similarity index 100% rename from src/app/medInria/medLogger.h rename to src/app/medInria/old/medLogger.h diff --git a/src/app/medInria/resources/configs/DataSourcesDefault.json b/src/app/medInria/resources/configs/DataSourcesDefault.json new file mode 100644 index 0000000000..48b56fcfa2 --- /dev/null +++ b/src/app/medInria/resources/configs/DataSourcesDefault.json @@ -0,0 +1,28 @@ +[ + { + "cnxId": "medTemporaryDataSource_210824", + "cnxName": "Temporary", + "parameters": { + "Flat Source": { + "caption": "Flat Source", + "description": "", + "id": "Flat Source", + "value": true + } + }, + "sourceType": "medTemporaryDataSource" + }, + { + "cnxId": "medSQLite_default", + "cnxName": "medSQLite_default", + "parameters": { + "LocalDataBasePath": { + "caption": "LocalDataBasePath", + "description": "", + "id": "LocalDataBasePath", + "value": "" + } + }, + "sourceType": "medSQLite" + } +] diff --git a/src/app/medInria/resources/medInria.qrc b/src/app/medInria/resources/medInria.qrc index 509dbb0a80..4af5d49a1f 100644 --- a/src/app/medInria/resources/medInria.qrc +++ b/src/app/medInria/resources/medInria.qrc @@ -125,6 +125,7 @@ icons/light/24x24/user_add.svg icons/3DIcon.png + icons/AxialIcon.png icons/checkbox-partial.png icons/connect_on.svg @@ -167,6 +168,6 @@ pixmaps/workspace_Reformat.png gif/icon.gif - + configs/DataSourcesDefault.json diff --git a/src/layers/legacy/medImageIO/CMakeLists.txt b/src/layers/legacy/medImageIO/CMakeLists.txt index 0562776d44..f031d943da 100644 --- a/src/layers/legacy/medImageIO/CMakeLists.txt +++ b/src/layers/legacy/medImageIO/CMakeLists.txt @@ -71,8 +71,8 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} PUBLIC - Qt5::Core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets med::Core @@ -155,6 +155,6 @@ set_lib_install_rules(${TARGET_NAME} PUBLIC_DEPENDENCIES "medInria REQUIRED COMPONENTS Core" "dtk REQUIRED" - "Qt5 REQUIRED COMPONENTS Core Widgets" + "Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets" "ITK REQUIRED COMPONENTS ITKVtkGlue ITKIOImageBase ITKIOMeta ITKZLIB" ) \ No newline at end of file diff --git a/src/layers/legacy/medImageIO/itkDataImageReaderBase.cpp b/src/layers/legacy/medImageIO/itkDataImageReaderBase.cpp index e61c4fe5f1..94311bbbe1 100644 --- a/src/layers/legacy/medImageIO/itkDataImageReaderBase.cpp +++ b/src/layers/legacy/medImageIO/itkDataImageReaderBase.cpp @@ -30,12 +30,12 @@ itkDataImageReaderBase::itkDataImageReaderBase() : medAbstractDataReader() { this->io = 0; - this->itkKeyToMedKey["intent_name"] = medAbstractImageData::PixelMeaningMetaData; - this->itkKeyToMedKey["MED_MODALITY"] = medMetaDataKeys::Modality.key(); - this->itkKeyToMedKey["MED_ORIENTATION"] = medMetaDataKeys::Orientation.key(); - // retrocompatibility - this->itkKeyToMedKey["SeriesDicomID"] = medMetaDataKeys::SeriesInstanceUID.key(); - this->itkKeyToMedKey["StudyDicomID"] = medMetaDataKeys::StudyInstanceUID.key(); + // this->itkKeyToMedKey["intent_name"] = medAbstractImageData::PixelMeaningMetaData; + // this->itkKeyToMedKey["MED_MODALITY"] = medMetaDataKeys::key("Modality"); + // this->itkKeyToMedKey["MED_ORIENTATION"] = medMetaDataKeys::key("Orientation"); + // // retrocompatibility + // this->itkKeyToMedKey["SeriesDicomID"] = medMetaDataKeys::key("SeriesInstanceUID"); + // this->itkKeyToMedKey["StudyDicomID"] = medMetaDataKeys::key("StudyInstanceUID"); } @@ -43,7 +43,7 @@ itkDataImageReaderBase::~itkDataImageReaderBase() { } -bool itkDataImageReaderBase::canRead (const QString& path) +bool itkDataImageReaderBase::canRead(const QString& path) { if (this->io.IsNull()) return false; @@ -51,7 +51,7 @@ bool itkDataImageReaderBase::canRead (const QString& path) // Avoid to display log of each metadata not read by itk::ImageIOBase this->io->SetGlobalWarningDisplay(false); - if (!this->io->CanReadFile( path.toUtf8().constData() )) + if (!this->io->CanReadFile(path.toUtf8().constData())) { return false; } @@ -62,18 +62,18 @@ bool itkDataImageReaderBase::canRead (const QString& path) // will be handled by more specific image readers // (e.g. tensors if 6 or 9 components) - this->io->SetFileName( path.toUtf8().constData() ); + this->io->SetFileName(path.toUtf8().constData()); try { - this->io->ReadImageInformation(); + this->io->ReadImageInformation(); } catch (itk::ExceptionObject &e) { - qDebug() << e.GetDescription(); - return false; + qDebug() << e.GetDescription(); + return false; } if (this->io->GetPixelType() == itk::IOPixelEnum::VECTOR) { - return this->io->GetNumberOfComponents() <= 4 ; + return this->io->GetNumberOfComponents() <= 4; } else { @@ -82,14 +82,14 @@ bool itkDataImageReaderBase::canRead (const QString& path) } } -bool itkDataImageReaderBase::canRead (const QStringList& paths) +bool itkDataImageReaderBase::canRead(const QStringList& paths) { if (!paths.count()) return false; - return this->canRead ( paths[0] ); + return this->canRead(paths[0]); } -bool itkDataImageReaderBase::readInformation (const QString& path) +bool itkDataImageReaderBase::readInformation(const QString& path) { if (this->io.IsNull()) return false; @@ -106,15 +106,15 @@ bool itkDataImageReaderBase::readInformation (const QString& path) } medAbstractData *medData = nullptr; - if (this->io->GetPixelType()==itk::IOPixelEnum::SCALAR ) + if (this->io->GetPixelType() == itk::IOPixelEnum::SCALAR) { - const int dim = this->io->GetNumberOfDimensions(); - if (!(dim>0 && dim<=4)) + const int dim = this->io->GetNumberOfDimensions(); + if (!(dim > 0 && dim <= 4)) { qDebug() << "Unrecognized component type"; return false; } - const char cdim = '0'+((dim<=3) ? 3 : 4); + const char cdim = '0' + ((dim <= 3) ? 3 : 4); switch (this->io->GetComponentType()) { @@ -124,39 +124,39 @@ bool itkDataImageReaderBase::readInformation (const QString& path) break; case itk::IOComponentEnum::CHAR: - medData = medAbstractDataFactory::instance()->create (QString("itkDataImageChar").append(cdim)); + medData = medAbstractDataFactory::instance()->create(QString("itkDataImageChar").append(cdim)); break; case itk::IOComponentEnum::USHORT: - medData = medAbstractDataFactory::instance()->create (QString("itkDataImageUShort").append(cdim)); + medData = medAbstractDataFactory::instance()->create(QString("itkDataImageUShort").append(cdim)); break; case itk::IOComponentEnum::SHORT: - medData = medAbstractDataFactory::instance()->create (QString("itkDataImageShort").append(cdim)); + medData = medAbstractDataFactory::instance()->create(QString("itkDataImageShort").append(cdim)); break; case itk::IOComponentEnum::UINT: - medData = medAbstractDataFactory::instance()->create (QString("itkDataImageUInt").append(cdim)); + medData = medAbstractDataFactory::instance()->create(QString("itkDataImageUInt").append(cdim)); break; case itk::IOComponentEnum::INT: - medData = medAbstractDataFactory::instance()->create (QString("itkDataImageInt").append(cdim)); + medData = medAbstractDataFactory::instance()->create(QString("itkDataImageInt").append(cdim)); break; case itk::IOComponentEnum::ULONG: - medData = medAbstractDataFactory::instance()->create (QString("itkDataImageULong").append(cdim)); + medData = medAbstractDataFactory::instance()->create(QString("itkDataImageULong").append(cdim)); break; case itk::IOComponentEnum::LONG: - medData = medAbstractDataFactory::instance()->create (QString("itkDataImageLong").append(cdim)); + medData = medAbstractDataFactory::instance()->create(QString("itkDataImageLong").append(cdim)); break; case itk::IOComponentEnum::FLOAT: - medData = medAbstractDataFactory::instance()->create (QString("itkDataImageDouble").append(cdim)); // Bug ??? + medData = medAbstractDataFactory::instance()->create(QString("itkDataImageDouble").append(cdim)); // Bug ??? break; case itk::IOComponentEnum::DOUBLE: - medData = medAbstractDataFactory::instance()->create (QString("itkDataImageDouble").append(cdim)); // Bug (added 4 which was not existing) ?? + medData = medAbstractDataFactory::instance()->create(QString("itkDataImageDouble").append(cdim)); // Bug (added 4 which was not existing) ?? break; default: @@ -164,14 +164,14 @@ bool itkDataImageReaderBase::readInformation (const QString& path) return false; } } - else if (this->io->GetPixelType()==itk::IOPixelEnum::RGB) + else if (this->io->GetPixelType() == itk::IOPixelEnum::RGB) { switch (this->io->GetComponentType()) { case itk::IOComponentEnum::UCHAR: - medData = medAbstractDataFactory::instance()->create ("itkDataImageRGB3"); + medData = medAbstractDataFactory::instance()->create("itkDataImageRGB3"); break; default: @@ -179,38 +179,38 @@ bool itkDataImageReaderBase::readInformation (const QString& path) return false; } } - else if (this->io->GetPixelType()==itk::IOPixelEnum::VECTOR) + else if (this->io->GetPixelType() == itk::IOPixelEnum::VECTOR) { // Added by Theo. switch (this->io->GetComponentType()) { case itk::IOComponentEnum::UCHAR: - medData = medAbstractDataFactory::instance()->create ("itkDataImageVectorUChar3"); + medData = medAbstractDataFactory::instance()->create("itkDataImageVectorUChar3"); break; case itk::IOComponentEnum::FLOAT: - medData = medAbstractDataFactory::instance()->create ("itkDataImageVectorFloat3"); + medData = medAbstractDataFactory::instance()->create("itkDataImageVectorFloat3"); break; case itk::IOComponentEnum::DOUBLE: - medData = medAbstractDataFactory::instance()->create ("itkDataImageVectorDouble3"); + medData = medAbstractDataFactory::instance()->create("itkDataImageVectorDouble3"); break; default: qDebug() << "Unrecognized component type"; return false; } } - else if ( this->io->GetPixelType()==itk::IOPixelEnum::RGBA ) + else if (this->io->GetPixelType() == itk::IOPixelEnum::RGBA) { switch (this->io->GetComponentType()) { - case itk::IOComponentEnum::UCHAR: - medData = medAbstractDataFactory::instance()->create ("itkDataImageRGBA3"); - break; + case itk::IOComponentEnum::UCHAR: + medData = medAbstractDataFactory::instance()->create("itkDataImageRGBA3"); + break; - default: - qDebug() << "Unrecognized component type"; - return false; + default: + qDebug() << "Unrecognized component type"; + return false; } } else @@ -219,38 +219,11 @@ bool itkDataImageReaderBase::readInformation (const QString& path) return false; } - // [HACK] : Some data have informations in their header but itk was not able to read them at this stage. - // the itk::readImageInformation method read only default tag defined by itk - // In case data was produced in MUSICardio for instance, a lot of tags are added (for identification purpose) - // A not exhaustive list of added tags : - // ContainsBasicInfo Description FilePaths ITK_InputFilterName PatientID PatientName SOPInstanceUID - // SeriesDescription SeriesDicomID SeriesID SeriesInstanceUID SeriesThumbnail Size StudyDescription StudyID - // We decide to read all available tags here if possible - itk::MetaDataDictionary& metaDataDictionary = this->io->GetMetaDataDictionary(); - std::vector keys = metaDataDictionary.GetKeys(); - - for (unsigned int i = 0; i < keys.size(); i++) - { - std::string key = keys[i]; - std::string value; - itk::ExposeMetaData(metaDataDictionary, key, value); - - QString metaDataKey = convertItkKeyToMedKey(key); - if (!metaDataKey.isEmpty()) - { - medData->setMetaData(metaDataKey, QString(value.c_str())); - } - else - { - qDebug() << metaObject()->className() << ":: found unknown key:" << QString::fromStdString(key); - } - } - // [END OF HACK] - if (medData) { this->setData(medData); - medData->addMetaData ("FilePath", QStringList() << path); + medData->addMetaData("FilePath", QStringList() << path); + extractMetaData(); return true; } else @@ -259,21 +232,21 @@ bool itkDataImageReaderBase::readInformation (const QString& path) } } -bool itkDataImageReaderBase::readInformation (const QStringList& paths) +bool itkDataImageReaderBase::readInformation(const QStringList& paths) { if (!paths.count()) return false; - return this->readInformation ( paths[0] ); + return this->readInformation(paths[0]); } -template -bool itkDataImageReaderBase::read_image(const QString& path,const char* type) +template +bool itkDataImageReaderBase::read_image(const QString& path, const char* type) { medAbstractData* medData = dynamic_cast(this->data()); - if ((medData && medData->identifier()!=type) || medData==nullptr) + if ((medData && medData->identifier() != type) || medData == nullptr) return false; - typedef itk::Image Image; + typedef itk::Image Image; typename itk::ImageFileReader::Pointer TReader = itk::ImageFileReader::New(); TReader->SetImageIO(this->io); TReader->SetFileName(path.toUtf8().constData()); @@ -282,54 +255,34 @@ bool itkDataImageReaderBase::read_image(const QString& path,const char* type) typename Image::Pointer im = TReader->GetOutput(); medData->setData(im); + medData->setMetaData("seriesdescription", QFileInfo(path).baseName()); - extractMetaData(); - - return true; + return extractMetaData(); } -QString itkDataImageReaderBase::convertItkKeyToMedKey(std::string& keyToConvert) -{ - QString convertedKey = ""; - - QString itkKey = QString::fromStdString(keyToConvert); - if (this->itkKeyToMedKey.contains(itkKey)) - { - convertedKey = this->itkKeyToMedKey[itkKey]; - } - else - { - const medMetaDataKeys::Key* medKey = medMetaDataKeys::Key::fromKeyName(keyToConvert.c_str()); - if (medKey) - { - convertedKey = medKey->key(); - } - } - - return convertedKey; -} - -void itkDataImageReaderBase::extractMetaData() +bool itkDataImageReaderBase::extractMetaData() { itk::Object* itkImage = static_cast(data()->data()); - itk::MetaDataDictionary& metaDataDictionary = itkImage->GetMetaDataDictionary(); - std::vector keys = metaDataDictionary.GetKeys(); - - for (unsigned int i = 0; i < keys.size(); i++) + if (itkImage) { - std::string key = keys[i]; - std::string value; - itk::ExposeMetaData(metaDataDictionary, key, value); + itk::MetaDataDictionary& metaDataDictionary = itkImage->GetMetaDataDictionary(); + std::vector keys = metaDataDictionary.GetKeys(); - QString metaDataKey = convertItkKeyToMedKey(key); - if (!metaDataKey.isEmpty()) + for (unsigned int i = 0; i < keys.size(); i++) { - data()->setMetaData(metaDataKey, QString(value.c_str())); - } - else - { - qDebug() << metaObject()->className() << ":: found unknown key:" << QString::fromStdString(key); + QString key = QString::fromStdString(keys[i]); + std::string value; + itk::ExposeMetaData(metaDataDictionary, keys[i], value); + + medMetaDataKeys::addKeyToChapter(key, "itk"); + QString metaDataKey = medMetaDataKeys::pivot(key, "itk"); + data()->setMetaData(metaDataKey, QString::fromStdString(value)); } + return true; + } + else + { + return false; } } @@ -340,7 +293,7 @@ bool itkDataImageReaderBase::read(const QString& path) this->setProgress(0); - if ( ! this->readInformation(path) ) + if (!this->readInformation(path)) return false; this->setProgress(50); @@ -353,31 +306,31 @@ bool itkDataImageReaderBase::read(const QString& path) try { - if (!(read_image<3,unsigned char>(path,"itkDataImageUChar3") || - read_image<3,char>(path,"itkDataImageChar3") || - read_image<3,unsigned short>(path,"itkDataImageUShort3") || - read_image<4,unsigned short>(path,"itkDataImageUShort4") || - read_image<4,unsigned int>(path,"itkDataImageUInt4") || - read_image<4,unsigned long>(path,"itkDataImageULong4") || - read_image<4,unsigned char>(path,"itkDataImageUChar4") || - read_image<4,char>(path,"itkDataImageChar4") || - read_image<4,long>(path,"itkDataImageLong4") || - read_image<4,int>(path,"itkDataImageInt4") || - read_image<3,short>(path,"itkDataImageShort3") || - read_image<4,short>(path,"itkDataImageShort4") || - read_image<3,unsigned int>(path,"itkDataImageUInt3") || - read_image<3,int>(path,"itkDataImageInt3") || - read_image<3,unsigned long>(path,"itkDataImageULong3") || - read_image<3,long>(path,"itkDataImageLong3") || - read_image<3,float>(path,"itkDataImageFloat3") || - read_image<4,float>(path,"itkDataImageFloat4") || - read_image<3,double>(path,"itkDataImageDouble3") || - read_image<4,double>(path,"itkDataImageDouble4") || - read_image<3,itk::Vector >(path,"itkDataImageVectorUChar3") || // Added by Theo. - read_image<3,itk::Vector >(path,"itkDataImageVectorFloat3") || - read_image<3,itk::Vector >(path,"itkDataImageVectorDouble3") || - read_image<3,itk::RGBAPixel >(path,"itkDataImageRGBA3") || - read_image<3,itk::RGBPixel >(path,"itkDataImageRGB3"))) + if (!(read_image<3, unsigned char>(path, "itkDataImageUChar3") || + read_image<3, char>(path, "itkDataImageChar3") || + read_image<3, unsigned short>(path, "itkDataImageUShort3") || + read_image<4, unsigned short>(path, "itkDataImageUShort4") || + read_image<4, unsigned int>(path, "itkDataImageUInt4") || + read_image<4, unsigned long>(path, "itkDataImageULong4") || + read_image<4, unsigned char>(path, "itkDataImageUChar4") || + read_image<4, char>(path, "itkDataImageChar4") || + read_image<4, long>(path, "itkDataImageLong4") || + read_image<4, int>(path, "itkDataImageInt4") || + read_image<3, short>(path, "itkDataImageShort3") || + read_image<4, short>(path, "itkDataImageShort4") || + read_image<3, unsigned int>(path, "itkDataImageUInt3") || + read_image<3, int>(path, "itkDataImageInt3") || + read_image<3, unsigned long>(path, "itkDataImageULong3") || + read_image<3, long>(path, "itkDataImageLong3") || + read_image<3, float>(path, "itkDataImageFloat3") || + read_image<4, float>(path, "itkDataImageFloat4") || + read_image<3, double>(path, "itkDataImageDouble3") || + read_image<4, double>(path, "itkDataImageDouble4") || + read_image<3, itk::Vector >(path, "itkDataImageVectorUChar3") || // Added by Theo. + read_image<3, itk::Vector >(path, "itkDataImageVectorFloat3") || + read_image<3, itk::Vector >(path, "itkDataImageVectorDouble3") || + read_image<3, itk::RGBAPixel >(path, "itkDataImageRGBA3") || + read_image<3, itk::RGBPixel >(path, "itkDataImageRGB3"))) { qWarning() << "Unrecognized pixel type"; return false; @@ -389,19 +342,19 @@ bool itkDataImageReaderBase::read(const QString& path) return false; } - this->setProgress (100); + this->setProgress(100); return true; } -bool itkDataImageReaderBase::read (const QStringList& paths) +bool itkDataImageReaderBase::read(const QStringList& paths) { if (paths.count() < 1) return false; return this->read(paths[0]); } -void itkDataImageReaderBase::setProgress (int value) +void itkDataImageReaderBase::setProgress(int value) { - emit progressed (value); + emit progressed(value); } diff --git a/src/layers/legacy/medImageIO/itkDataImageReaderBase.h b/src/layers/legacy/medImageIO/itkDataImageReaderBase.h index b183280112..41426a384a 100644 --- a/src/layers/legacy/medImageIO/itkDataImageReaderBase.h +++ b/src/layers/legacy/medImageIO/itkDataImageReaderBase.h @@ -52,5 +52,5 @@ public slots: private: template bool read_image(const QString& path,const char* type); - void extractMetaData(); + bool extractMetaData(); }; diff --git a/src/layers/legacy/medImageIO/itkDataImageWriterBase.cpp b/src/layers/legacy/medImageIO/itkDataImageWriterBase.cpp index a890d0bad0..622b35069a 100644 --- a/src/layers/legacy/medImageIO/itkDataImageWriterBase.cpp +++ b/src/layers/legacy/medImageIO/itkDataImageWriterBase.cpp @@ -4,7 +4,7 @@ Copyright (c) INRIA 2013 - 2018. All rights reserved. See LICENSE.txt for details. - + This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -32,8 +32,8 @@ itkDataImageWriterBase::itkDataImageWriterBase() this->io = 0; this->medKeyToItkKey[medAbstractImageData::PixelMeaningMetaData] = "intent_name"; - this->medKeyToItkKey[medMetaDataKeys::Modality.key()] = "MED_MODALITY"; - this->medKeyToItkKey[medMetaDataKeys::Orientation.key()] = "MED_ORIENTATION"; + this->medKeyToItkKey[medMetaDataKeys::key("Modality")] = "MED_MODALITY"; + this->medKeyToItkKey[medMetaDataKeys::key("Orientation")] = "MED_ORIENTATION"; } itkDataImageWriterBase::~itkDataImageWriterBase() @@ -45,35 +45,25 @@ bool itkDataImageWriterBase::canWrite(const QString& path) if (this->io.IsNull()) return false; - return this->io->CanWriteFile ( path.toUtf8().constData() ); + return this->io->CanWriteFile(path.toUtf8().constData()); } -template -bool itkDataImageWriterBase::write_image(const QString& path,const char* type){ +template +bool itkDataImageWriterBase::write_image(const QString& path, const char* type) { medAbstractData* medData = dynamic_cast(this->data()); if (medData && medData->identifier() != type) - { return false; - } - typedef itk::Image Image; + typedef itk::Image Image; typename Image::Pointer image = dynamic_cast((itk::Object*)(this->data()->output())); if (image.IsNull()) - { return false; - } - - itk::MetaDataDictionary& dict = image->GetMetaDataDictionary(); - if (medData->hasMetaData(medAbstractImageData::PixelMeaningMetaData)) - { + if (medData->hasMetaData(medAbstractImageData::PixelMeaningMetaData)) { + itk::MetaDataDictionary& dict = image->GetMetaDataDictionary(); itk::EncapsulateMetaData(dict, "intent_name", medData->metadata(medAbstractImageData::PixelMeaningMetaData)); } - - // save relevant metaDataKeys - encapsulateSharedMetaData(dict); - typename itk::ImageFileWriter::Pointer writer = itk::ImageFileWriter ::New(); - writer->SetImageIO (this->io); + writer->SetImageIO(this->io); writer->UseCompressionOn(); writer->SetFileName(path.toUtf8().constData()); writer->SetInput(image); @@ -97,21 +87,6 @@ std::string itkDataImageWriterBase::convertMedKeyToItkKey(QString medKey) return itkKey; } -void itkDataImageWriterBase::encapsulateSharedMetaData(itk::MetaDataDictionary& dict) -{ - itk::Object* itkImage = static_cast(data()->data()); - itk::MetaDataDictionary& metaDataDictionary = itkImage->GetMetaDataDictionary(); - - foreach (QString metaDataKey, data()->metaDataList()) - { - if (medMetaDataKeys::Key::fromKeyName(metaDataKey.toStdString().c_str())) - { - std::string key = convertMedKeyToItkKey(metaDataKey); - itk::EncapsulateMetaData(metaDataDictionary, key, data()->metadata(metaDataKey).toStdString()); - } - } -} - bool itkDataImageWriterBase::write(const QString& path) { if (!this->data()) @@ -122,37 +97,38 @@ bool itkDataImageWriterBase::write(const QString& path) try { - if (!(write_image<3,unsigned char>(path,"itkDataImageUChar3") || - write_image<3,char>(path,"itkDataImageChar3") || - write_image<3,unsigned short>(path,"itkDataImageUShort3") || - write_image<4,unsigned short>(path,"itkDataImageUShort4") || - write_image<4,unsigned int>(path,"itkDataImageUInt4") || - write_image<4,unsigned long>(path,"itkDataImageULong4") || - write_image<4,unsigned char>(path,"itkDataImageUChar4") || - write_image<4,char>(path,"itkDataImageChar4") || - write_image<4,long>(path,"itkDataImageLong4") || - write_image<4,int>(path,"itkDataImageInt4") || - write_image<3,short>(path,"itkDataImageShort3") || - write_image<4,short>(path,"itkDataImageShort4") || - write_image<3,unsigned int>(path,"itkDataImageUInt3") || - write_image<3,int>(path,"itkDataImageInt3") || - write_image<3,unsigned long>(path,"itkDataImageULong3") || - write_image<3,long>(path,"itkDataImageLong3") || - write_image<3,float>(path,"itkDataImageFloat3") || - write_image<4,float>(path,"itkDataImageFloat4") || - write_image<3,double>(path,"itkDataImageDouble3") || - write_image<4,double>(path,"itkDataImageDouble4") || - write_image<3,itk::Vector >(path,"itkDataImageVectorUChar3") || // Added by Theo. - write_image<3,itk::Vector >(path,"itkDataImageVectorFloat3") || - write_image<3,itk::Vector >(path,"itkDataImageVectorDouble3") || - write_image<3,itk::RGBAPixel >(path,"itkDataImageRGBA3") || - write_image<3,itk::RGBPixel >(path,"itkDataImageRGB3"))) + if (!(write_image<3, unsigned char>(path, "itkDataImageUChar3") || + write_image<3, char>(path, "itkDataImageChar3") || + write_image<3, unsigned short>(path, "itkDataImageUShort3") || + write_image<4, unsigned short>(path, "itkDataImageUShort4") || + write_image<4, unsigned int>(path, "itkDataImageUInt4") || + write_image<4, unsigned long>(path, "itkDataImageULong4") || + write_image<4, unsigned char>(path, "itkDataImageUChar4") || + write_image<4, char>(path, "itkDataImageChar4") || + write_image<4, long>(path, "itkDataImageLong4") || + write_image<4, int>(path, "itkDataImageInt4") || + write_image<3, short>(path, "itkDataImageShort3") || + write_image<4, short>(path, "itkDataImageShort4") || + write_image<3, unsigned int>(path, "itkDataImageUInt3") || + write_image<3, int>(path, "itkDataImageInt3") || + write_image<3, unsigned long>(path, "itkDataImageULong3") || + write_image<3, long>(path, "itkDataImageLong3") || + write_image<3, float>(path, "itkDataImageFloat3") || + write_image<4, float>(path, "itkDataImageFloat4") || + write_image<3, double>(path, "itkDataImageDouble3") || + write_image<4, double>(path, "itkDataImageDouble4") || + write_image<3, itk::Vector >(path, "itkDataImageVectorUChar3") || // Added by Theo. + write_image<3, itk::Vector >(path, "itkDataImageVectorFloat3") || + write_image<3, itk::Vector >(path, "itkDataImageVectorDouble3") || + write_image<3, itk::RGBAPixel >(path, "itkDataImageRGBA3") || + write_image<3, itk::RGBPixel >(path, "itkDataImageRGB3"))) { dtkWarn() << "Unrecognized pixel type"; return false; } - } catch(itk::ExceptionObject &e) { + } + catch (itk::ExceptionObject &e) { dtkDebug() << e.GetDescription(); return false; } @@ -168,8 +144,8 @@ QStringList itkDataImageWriterBase::supportedFileExtensions() const if (this->io) { typedef itk::ImageIOBase::ArrayOfExtensionsType ArrayOfExtensionsType; const ArrayOfExtensionsType & extensions = this->io->GetSupportedWriteExtensions(); - for( ArrayOfExtensionsType::const_iterator it(extensions.begin()); - it != extensions.end(); ++it ) + for (ArrayOfExtensionsType::const_iterator it(extensions.begin()); + it != extensions.end(); ++it) { ret << it->c_str(); } diff --git a/src/layers/legacy/medLog/CMakeLists.txt b/src/layers/legacy/medLog/CMakeLists.txt index d5a2dac993..86360c114a 100644 --- a/src/layers/legacy/medLog/CMakeLists.txt +++ b/src/layers/legacy/medLog/CMakeLists.txt @@ -70,8 +70,8 @@ target_include_directories(${TARGET_NAME} ## ############################################################################# target_link_libraries(${TARGET_NAME} PUBLIC - Qt5::Core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets ITKCommon VTK::CommonCore # dtk @@ -97,6 +97,6 @@ set_lib_install_rules(${TARGET_NAME} PUBLIC_DEPENDENCIES "medInria REQUIRED COMPONENTS Core" "dtk REQUIRED COMPONENTS dtkLog dtkCoreSupport " - "Qt5 REQUIRED COMPONENTS Core Widgets" + "Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets" "ITK REQUIRED COMPONENTS ITKCommon" ) \ No newline at end of file diff --git a/src/layers/legacy/medRegistration/CMakeLists.txt b/src/layers/legacy/medRegistration/CMakeLists.txt index 5669d44689..a69aa4ad80 100644 --- a/src/layers/legacy/medRegistration/CMakeLists.txt +++ b/src/layers/legacy/medRegistration/CMakeLists.txt @@ -69,8 +69,8 @@ target_include_directories(${TARGET_NAME} ## ############################################################################# target_link_libraries(${TARGET_NAME} PUBLIC - Qt5::Core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets med::Core @@ -129,7 +129,7 @@ set_lib_install_rules(${TARGET_NAME} PUBLIC_DEPENDENCIES "medInria REQUIRED COMPONENTS Core" "dtk REQUIRED" - "Qt5 REQUIRED COMPONENTS Core Widgets" + "Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets" "ITK REQUIRED COMPONENTS ITKIOImageBase ITKTransform ITKIOTransformBase ITKIOTransformInsightLegacy ITKRegistrationCommon ITKIOMeta" "RPI REQUIRED COMPONENTS Common" ) \ No newline at end of file diff --git a/src/layers/legacy/medUtilities/medUtilities.cpp b/src/layers/legacy/medUtilities/medUtilities.cpp index 1f82213900..0145615760 100644 --- a/src/layers/legacy/medUtilities/medUtilities.cpp +++ b/src/layers/legacy/medUtilities/medUtilities.cpp @@ -40,18 +40,18 @@ void medUtilities::setDerivedMetaData(medAbstractData* derived, medAbstractData* QString newSeriesDescription; if (outputSchema) { - newSeriesDescription = original->metadata(medMetaDataKeys::SeriesDescription.key()); + newSeriesDescription = original->fecthMetaData("SeriesDescription"); newSeriesDescription += " (" + derivationDescription + ")"; } else { newSeriesDescription = derivationDescription; } - derived->setMetaData(medMetaDataKeys::SeriesDescription.key(), newSeriesDescription); + derived->setMetaData(medMetaDataKeys::key("SeriesDescription").medPivot(), newSeriesDescription); } else { - derived->setMetaData(medMetaDataKeys::SeriesDescription.key(), original->metadata(medMetaDataKeys::SeriesDescription.key())); + derived->setMetaData(medMetaDataKeys::key("SeriesDescription").medPivot(), original->fecthMetaData("SeriesDescription")); } if (queryForDescription) @@ -76,7 +76,7 @@ void medUtilities::copyMetaDataIfEmpty(medAbstractData* derived, medAbstractData { if (!derived->hasMetaData(metaDataKey) && original->hasMetaData(metaDataKey)) { - derived->setMetaData(metaDataKey, original->metadata(metaDataKey)); + derived->setMetaData(metaDataKey, original->fecthMetaData(metaDataKey)); } } @@ -84,54 +84,54 @@ QStringList medUtilities::metaDataKeysToCopyForDerivedData(medAbstractData* deri { QStringList keys; - keys << medMetaDataKeys::PatientID.key() - << medMetaDataKeys::PatientName.key() - << medMetaDataKeys::Age.key() - << medMetaDataKeys::BirthDate.key() - << medMetaDataKeys::Gender.key() - << medMetaDataKeys::Description.key() - << medMetaDataKeys::StudyID.key() - << medMetaDataKeys::StudyInstanceUID.key() - << medMetaDataKeys::StudyDescription.key() - << medMetaDataKeys::Institution.key() - << medMetaDataKeys::Referee.key() - << medMetaDataKeys::StudyDate.key() - << medMetaDataKeys::StudyTime.key() - << medMetaDataKeys::Modality.key() - << medMetaDataKeys::Performer.key() - << medMetaDataKeys::Report.key() - << medMetaDataKeys::Protocol.key() - << medMetaDataKeys::Orientation.key() - << medMetaDataKeys::Origin.key() - << medMetaDataKeys::AcquisitionDate.key() - << medMetaDataKeys::AcquisitionTime.key(); + keys << medMetaDataKeys::key("PatientID") + << medMetaDataKeys::key("PatientName") + << medMetaDataKeys::key("Age") + << medMetaDataKeys::key("BirthDate") + << medMetaDataKeys::key("Gender") + << medMetaDataKeys::key("Description") + << medMetaDataKeys::key("StudyID") + << medMetaDataKeys::key("StudyInstanceUID") + << medMetaDataKeys::key("StudyDescription") + << medMetaDataKeys::key("Institution") + << medMetaDataKeys::key("Referee") + << medMetaDataKeys::key("StudyDate") + << medMetaDataKeys::key("StudyTime") + << medMetaDataKeys::key("Modality") + << medMetaDataKeys::key("Performer") + << medMetaDataKeys::key("Report") + << medMetaDataKeys::key("Protocol") + << medMetaDataKeys::key("Orientation") + << medMetaDataKeys::key("Origin") + << medMetaDataKeys::key("AcquisitionDate") + << medMetaDataKeys::key("AcquisitionTime"); if (qobject_cast(derived)) { - keys << medMetaDataKeys::Columns.key() - << medMetaDataKeys::Rows.key() - << medMetaDataKeys::Dimensions.key() - << medMetaDataKeys::NumberOfDimensions.key() - << medMetaDataKeys::SliceThickness.key() - << medMetaDataKeys::Spacing.key() - << medMetaDataKeys::XSpacing.key() - << medMetaDataKeys::YSpacing.key() - << medMetaDataKeys::ZSpacing.key() - << medMetaDataKeys::NumberOfComponents.key() - << medMetaDataKeys::ComponentType.key() - << medMetaDataKeys::PixelType.key() - << medMetaDataKeys::PatientPosition.key() - << medMetaDataKeys::PatientOrientation.key() - << medMetaDataKeys::ImageType.key() - << medMetaDataKeys::AcquisitionNumber.key() - << medMetaDataKeys::FrameOfReferenceUID.key() - << medMetaDataKeys::PositionReferenceIndicator.key() - << medMetaDataKeys::FrameOfReferenceUID.key() - << medMetaDataKeys::Manufacturer.key() - << medMetaDataKeys::KVP.key() - << medMetaDataKeys::FlipAngle.key() - << medMetaDataKeys::EchoTime.key() - << medMetaDataKeys::RepetitionTime.key(); + keys << medMetaDataKeys::key("Columns") + << medMetaDataKeys::key("Rows") + << medMetaDataKeys::key("Dimensions") + << medMetaDataKeys::key("NumberOfDimensions") + << medMetaDataKeys::key("SliceThickness") + << medMetaDataKeys::key("Spacing") + << medMetaDataKeys::key("XSpacing") + << medMetaDataKeys::key("YSpacing") + << medMetaDataKeys::key("ZSpacing") + << medMetaDataKeys::key("NumberOfComponents") + << medMetaDataKeys::key("ComponentType") + << medMetaDataKeys::key("PixelType") + << medMetaDataKeys::key("PatientPosition") + << medMetaDataKeys::key("PatientOrientation") + << medMetaDataKeys::key("ImageType") + << medMetaDataKeys::key("AcquisitionNumber") + << medMetaDataKeys::key("FrameOfReferenceUID") + << medMetaDataKeys::key("PositionReferenceIndicator") + << medMetaDataKeys::key("FrameOfReferenceUID") + << medMetaDataKeys::key("Manufacturer") + << medMetaDataKeys::key("KVP") + << medMetaDataKeys::key("FlipAngle") + << medMetaDataKeys::key("EchoTime") + << medMetaDataKeys::key("RepetitionTime"); } return keys; @@ -147,28 +147,28 @@ void medUtilities::generateStudyIdAndInstanceUid(medAbstractData* data) { gdcm::UIDGenerator uidGenerator; QString generatedStudyId = QString::fromStdString(uidGenerator.Generate()); - data->setMetaData(medMetaDataKeys::StudyID.key(), generatedStudyId); + data->setMetaData(medMetaDataKeys::key("StudyID").medPivot(), generatedStudyId); QString generatedStudyInstanceUid = QString::fromStdString(uidGenerator.Generate()); - data->setMetaData(medMetaDataKeys::StudyInstanceUID.key(), generatedStudyInstanceUid); + data->setMetaData(medMetaDataKeys::key("StudyInstanceUID").medPivot(), generatedStudyInstanceUid); } void medUtilities::generateSeriesAndSOPInstanceId(medAbstractData* data) { gdcm::UIDGenerator uidGenerator; QString generatedSeriesID = QString::fromStdString(uidGenerator.Generate()); - data->setMetaData(medMetaDataKeys::SeriesID.key(), generatedSeriesID); + data->setMetaData(medMetaDataKeys::key("SeriesID").medPivot(), generatedSeriesID); QString generatedSOPInstanceID = QString::fromStdString(uidGenerator.Generate()); - data->setMetaData(medMetaDataKeys::SOPInstanceUID.key(), generatedSOPInstanceID); + data->setMetaData(medMetaDataKeys::key("SOPInstanceUID").medPivot(), generatedSOPInstanceID); QString generatedSeriesInstanceUID = QString::fromStdString(uidGenerator.Generate()); - data->setMetaData(medMetaDataKeys::SeriesInstanceUID.key(), generatedSeriesInstanceUID); + data->setMetaData(medMetaDataKeys::key("SeriesInstanceUID").medPivot(), generatedSeriesInstanceUID); } void medUtilities::querySeriesDescription(medAbstractData* data) { - QString currentDescription = data->metadata(medMetaDataKeys::SeriesDescription.key()); + QString currentDescription = data->fecthMetaData("SeriesDescription"); QString queriedDescription = QInputDialog::getText(nullptr, "Series description", "Enter the name of the series:", QLineEdit::Normal, currentDescription); if (!queriedDescription.isEmpty()) @@ -176,7 +176,7 @@ void medUtilities::querySeriesDescription(medAbstractData* data) currentDescription = queriedDescription; } - data->setMetaData(medMetaDataKeys::SeriesDescription.key(), currentDescription); + data->setMetaData(medMetaDataKeys::key("SeriesDescription").medPivot(), currentDescription); } void medUtilities::applyOrientationMatrix(medAbstractView* view, double* inPoint, double* outPoint, bool withTranslation) diff --git a/src/layers/legacy/medUtilities/medUtilitiesITK.h b/src/layers/legacy/medUtilities/medUtilitiesITK.h index 1f71c90d89..b5488848fd 100644 --- a/src/layers/legacy/medUtilities/medUtilitiesITK.h +++ b/src/layers/legacy/medUtilities/medUtilitiesITK.h @@ -157,16 +157,16 @@ class MEDUTILITIES_EXPORT medUtilitiesITK { typename ImageType::Pointer outputImage = static_cast(outputData->data()); - outputData->setMetaData(medMetaDataKeys::Columns.key(), + outputData->setMetaData(medMetaDataKeys::key("Columns").medPivot(), QString::number(outputImage->GetLargestPossibleRegion().GetSize()[0])); - outputData->setMetaData(medMetaDataKeys::Rows.key(), + outputData->setMetaData(medMetaDataKeys::key("Rows").medPivot(), QString::number(outputImage->GetLargestPossibleRegion().GetSize()[1])); - outputData->setMetaData(medMetaDataKeys::Size.key(), + outputData->setMetaData(medMetaDataKeys::key("Size").medPivot(), QString::number(outputImage->GetLargestPossibleRegion().GetSize()[2])); - outputData->setMetaData(medMetaDataKeys::SliceThickness.key(), + outputData->setMetaData(medMetaDataKeys::key("SliceThickness").medPivot(), QString::number(outputImage->GetSpacing()[2])); - outputData->setMetaData(medMetaDataKeys::Orientation.key(), + outputData->setMetaData(medMetaDataKeys::key("Orientation").medPivot(), QString::number(outputImage->GetDirection()[0][0]) + QString(" ") + QString::number(outputImage->GetDirection()[0][1]) + @@ -179,7 +179,7 @@ class MEDUTILITIES_EXPORT medUtilitiesITK QString(" ") + QString::number(outputImage->GetDirection()[1][2])); - outputData->setMetaData(medMetaDataKeys::Origin.key(), + outputData->setMetaData(medMetaDataKeys::key("Origin").medPivot(), QString::number(outputImage->GetOrigin()[0]) + QString(" ") + QString::number(outputImage->GetOrigin()[1]) + diff --git a/src/layers/legacy/medVtkInria/CMakeLists.txt b/src/layers/legacy/medVtkInria/CMakeLists.txt index daf4c60ea7..f2ec36fcf3 100644 --- a/src/layers/legacy/medVtkInria/CMakeLists.txt +++ b/src/layers/legacy/medVtkInria/CMakeLists.txt @@ -78,8 +78,9 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} PUBLIC ${OPENGL_LIBRARIES} - Qt5::Core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + med::Core ${VTK_OSPRAY_RENDERING_LIBRARY} ${VTK_LIBRARIES} diff --git a/src/layers/medCore/CMakeLists.txt b/src/layers/medCore/CMakeLists.txt index aab838f383..ba993f88d6 100644 --- a/src/layers/medCore/CMakeLists.txt +++ b/src/layers/medCore/CMakeLists.txt @@ -23,8 +23,8 @@ set(TARGET_NAME medCore) find_package(dtk REQUIRED) include_directories(${dtk_INCLUDE_DIRS}) -find_package(Qt5Test REQUIRED) -find_package(Qt5 REQUIRED Network) +find_package(Qt${QT_VERSION_MAJOR}Test REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED Network) ## ############################################################################# ## List Sources @@ -102,18 +102,18 @@ target_link_libraries(${TARGET_NAME} dtkCoreSupport dtkGuiSupport - Qt5::Core - Qt5::Xml - Qt5::Widgets - Qt5::OpenGL - Qt5::Gui - Qt5::Sql - Qt5::Test + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Xml + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::OpenGL + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Sql + Qt${QT_VERSION_MAJOR}::Test ${OPENGL_LIBRARIES} PRIVATE dtkLog - Qt5::Network + Qt${QT_VERSION_MAJOR}::Network ) ## ############################################################################# @@ -128,5 +128,5 @@ set_lib_install_rules(${TARGET_NAME} PUBLIC_DEPENDENCIES "dtk REQUIRED COMPONENTS dtkCore dtkCoreSupport dtkGuiSupport" - "Qt5 REQUIRED COMPONENTS Core Xml Widgets OpenGL Gui Sql Test" + "Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Xml Widgets OpenGL Gui Sql Test" ) diff --git a/src/layers/medCore/legacy/data/medAbstractData.cpp b/src/layers/medCore/legacy/data/medAbstractData.cpp index ed670d9290..6c5b9cbc79 100644 --- a/src/layers/medCore/legacy/data/medAbstractData.cpp +++ b/src/layers/medCore/legacy/data/medAbstractData.cpp @@ -37,6 +37,8 @@ class medAbstractDataPrivate QList derivedDataList; QString expectedName; + //QMap metaDataMap; + QImage thumbnail; }; @@ -168,6 +170,38 @@ void medAbstractData::clearAttachedData() d->attachedData.clear(); } +QString medAbstractData::fecthMetaData(QString word) const +{ + QString metaDataRes; + + if (hasMetaData(word)) + { + metaDataRes = metadata(word); + } + else + { + Key2 key = medMetaDataKeys::key(word); + if (key.isValid()) + { + metaDataRes = medMetaDataKeys::getValue(key, getMetaDataMap()); + } + } + + return metaDataRes; +} + +QMap medAbstractData::getMetaDataMap() const +{ + QMap metaDataListRes; + + for (QString k : this->metaDataList()) + { + metaDataListRes[k] = metaDataValues(k).join(';'); + } + + return metaDataListRes; +} + /** * @brief add attached data * @@ -341,6 +375,38 @@ QString medAbstractData::getExpectedName() return d->expectedName; } +// QStringList medAbstractData::metaDataList(void) const +// { +// QStringList res; +// +// auto key2Lst = d->metaDataMap.keys(); +// for (auto key : key2Lst) +// { +// res << key.medPivot(); +// } +// +// return res; +// } +// +// QStringList medAbstractData::metadatas(Key2 const &key) +// { +// return d->metaDataMap.value(key); +// } +// +// void medAbstractData::setMetaData(Key2 const &key, QStringList value) +// { +// if (!medMetaDataKeys::keyExist(key)) +// { +// medMetaDataKeys::registerKey(key); +// } +// d->metaDataMap[key] = value; +// } +// +// void medAbstractData::setMetaData(Key2 const & key, QString value) +// { +// setMetaData(key, QStringList() << value); +// } + void medAbstractData::setExpectedName(QString name) { d->expectedName = name; diff --git a/src/layers/medCore/legacy/data/medAbstractData.h b/src/layers/medCore/legacy/data/medAbstractData.h index 80090c4a5c..ad4dbf3408 100644 --- a/src/layers/medCore/legacy/data/medAbstractData.h +++ b/src/layers/medCore/legacy/data/medAbstractData.h @@ -15,6 +15,7 @@ #include #include +#include class medAbstractDataPrivate; class medAttachedData; @@ -49,6 +50,8 @@ class MEDCORE_EXPORT medAbstractData : public dtkAbstractData virtual QImage generateThumbnail(QSize size); + + // FLO & JU bool addParentData(medAbstractData * pi_parentData); bool addDerivedData(medAbstractData * pi_derivedData); @@ -59,6 +62,27 @@ class MEDCORE_EXPORT medAbstractData : public dtkAbstractData void setExpectedName(QString name); QString getExpectedName(); + + // //void addMetaData(const QString& key, const QStringList& values); + // //void addMetaData(const QString& key, const QString& value); + // void setMetaData(const QString& key, const QStringList& values) { setMetaData(Key2(key), values); } + // void setMetaData(const QString& key, const QString& value) { setMetaData(Key2(key), value); } + // + // QStringList metaDataList(void) const; + // QStringList metaDataValues(const QString& key) const { return metadatas(key); } + // QString metadata(const QString& key) const { return metadata(Key2(key)); } + // QStringList metadatas(const QString& key) const { return metadatas(Key2(key)); } + // + // + // QStringList metadatas(Key2 const &key); + // QString metadata(Key2 const &key) { auto resLst = metadatas(key); return resLst.size() == 0 ? QString() : resLst[0]; } + // void setMetaData(Key2 const &key, QStringList value); + // void setMetaData(Key2 const &key, QString value); + QString fecthMetaData(QString word) const; + + QMap getMetaDataMap() const; + + //virtual QByteArray serialise() const = 0 ; public slots: void clearAttachedData(); void addAttachedData( medAttachedData * data ); diff --git a/src/layers/medCore/legacy/data/medAbstractDataReader.cpp b/src/layers/medCore/legacy/data/medAbstractDataReader.cpp index 8c8edcf07d..0c2a6be411 100644 --- a/src/layers/medCore/legacy/data/medAbstractDataReader.cpp +++ b/src/layers/medCore/legacy/data/medAbstractDataReader.cpp @@ -29,3 +29,14 @@ QList medAbstractDataReader::getDataList() { return dataList; } + +// TODO : considering a hash function for the file to generate the serial number +QString medAbstractDataReader::getVolumeId(const QString& path) +{ + return QFileInfo(path).baseName(); +} + +QString medAbstractDataReader::getVolumeName(const QString& path) +{ + return QFileInfo(path).baseName(); +} diff --git a/src/layers/medCore/legacy/data/medAbstractDataReader.h b/src/layers/medCore/legacy/data/medAbstractDataReader.h index 6a606d5b03..d9f362d059 100644 --- a/src/layers/medCore/legacy/data/medAbstractDataReader.h +++ b/src/layers/medCore/legacy/data/medAbstractDataReader.h @@ -31,6 +31,9 @@ class MEDCORE_EXPORT medAbstractDataReader : public dtkAbstractDataReader virtual void setData(dtkAbstractData* data); QList getDataList(); + virtual QString getVolumeId(const QString& path); + virtual QString getVolumeName(const QString& path); + private: QList dataList; }; diff --git a/src/layers/medCore/legacy/data/medAbstractDiffusionModelImageData.cpp b/src/layers/medCore/legacy/data/medAbstractDiffusionModelImageData.cpp index ec0014eec5..ef48d9cfb7 100644 --- a/src/layers/medCore/legacy/data/medAbstractDiffusionModelImageData.cpp +++ b/src/layers/medCore/legacy/data/medAbstractDiffusionModelImageData.cpp @@ -21,6 +21,6 @@ medAbstractDiffusionModelImageData::medAbstractDiffusionModelImageData() : medAb const QString medAbstractDiffusionModelImageData::PixelMeaning() const { if (hasMetaData(medAbstractImageData::PixelMeaningMetaData)) - return metadata(medAbstractImageData::PixelMeaningMetaData); + return fecthMetaData(medAbstractImageData::PixelMeaningMetaData); return ""; } diff --git a/src/layers/medCore/legacy/data/medAbstractTypedImageData.h b/src/layers/medCore/legacy/data/medAbstractTypedImageData.h index 9edbd23258..d796a83359 100644 --- a/src/layers/medCore/legacy/data/medAbstractTypedImageData.h +++ b/src/layers/medCore/legacy/data/medAbstractTypedImageData.h @@ -23,7 +23,7 @@ class medAbstractTypedImageData: public medAbstractImageData { virtual const QString PixelMeaning() const { if (hasMetaData(medAbstractImageData::PixelMeaningMetaData)) - return metadata(medAbstractImageData::PixelMeaningMetaData); + return fecthMetaData(medAbstractImageData::PixelMeaningMetaData); return ""; } }; diff --git a/src/layers/medCore/legacy/data/medMetaDataKeys.cpp b/src/layers/medCore/legacy/data/medMetaDataKeys.cpp index e215961b3e..bdbae8941a 100644 --- a/src/layers/medCore/legacy/data/medMetaDataKeys.cpp +++ b/src/layers/medCore/legacy/data/medMetaDataKeys.cpp @@ -13,99 +13,677 @@ #include -namespace medMetaDataKeys -{ - MEDCORE_EXPORT Key::Registery Key::registery; - - /** Define the actual keys to use */ - - MEDCORE_EXPORT const Key TransferSyntaxUID("TransferSyntaxUID"); - MEDCORE_EXPORT const Key ContainsBasicInfo("ContainsBasicInfo"); - - // PATIENT - MEDCORE_EXPORT const Key PatientID("PatientID"); - MEDCORE_EXPORT const Key PatientName("PatientName", "Patient Name"); - MEDCORE_EXPORT const Key Age("Age", "Age"); // could be "00" format, or for instance "00Y" - MEDCORE_EXPORT const Key BirthDate("BirthDate", "Birth Date"/*, QVariant::Date*/); - MEDCORE_EXPORT const Key Gender("Gender", "Gender", QVariant::Char); - MEDCORE_EXPORT const Key Description("Description"); // Used to add the app name and version - - // STUDY - MEDCORE_EXPORT const Key StudyID("StudyID", "Study ID"); - MEDCORE_EXPORT const Key StudyInstanceUID("StudyInstanceUID", "Study Instance UID"); - MEDCORE_EXPORT const Key StudyDescription("StudyDescription", "Study Description"); - MEDCORE_EXPORT const Key Institution("Institution"); - MEDCORE_EXPORT const Key Referee("Referee"); - MEDCORE_EXPORT const Key StudyDate("StudyDate", "Study Date"/*, QVariant::Date*/); - MEDCORE_EXPORT const Key StudyTime("StudyTime", "Study Time"/*, QVariant::Date*/); - - // SERIES - MEDCORE_EXPORT const Key SeriesID("SeriesID", "Series ID"); - MEDCORE_EXPORT const Key SeriesInstanceUID("SeriesInstanceUID", "Series Instance UID"); - MEDCORE_EXPORT const Key SeriesNumber("SeriesNumber", "Series Number"); - MEDCORE_EXPORT const Key Modality("Modality"); - MEDCORE_EXPORT const Key Performer("Performer"); - MEDCORE_EXPORT const Key Report("Report"); - MEDCORE_EXPORT const Key Protocol("Protocol"); - MEDCORE_EXPORT const Key SeriesDescription("SeriesDescription", "Series Description"); - MEDCORE_EXPORT const Key SeriesDate("SeriesDate", "Series Date"/*, QVariant::Date*/); - MEDCORE_EXPORT const Key SeriesTime("SeriesTime", "Series Time"/*, QVariant::Date*/); - MEDCORE_EXPORT const Key SeriesThumbnail("SeriesThumbnail", "Series Thumbnail"); - - // EQUIPEMENT - MEDCORE_EXPORT const Key Manufacturer("Manufacturer", "Manufacturer"); - - // IMAGE - MEDCORE_EXPORT const Key SOPInstanceUID("SOPInstanceUID", "SOP Instance UID"); - MEDCORE_EXPORT const Key Columns("Columns","Columns",QVariant::UInt); - MEDCORE_EXPORT const Key Rows("Rows","Rows",QVariant::UInt); - MEDCORE_EXPORT const Key Dimensions("Dimensions","Dimensions",QVariant::Int); - MEDCORE_EXPORT const Key NumberOfDimensions("NumberOfDimensions", "Number Of Dimensions"); - MEDCORE_EXPORT const Key Orientation("Orientation"); - MEDCORE_EXPORT const Key Origin("Origin"); - MEDCORE_EXPORT const Key SliceThickness("SliceThickness", "Slice Thickness"); - MEDCORE_EXPORT const Key ImportationDate("ImportationDate", "Importation Date"); - MEDCORE_EXPORT const Key AcquisitionDate("AcquisitionDate", "Acquisition Date"); - MEDCORE_EXPORT const Key AcquisitionTime("AcquisitionTime", "Acquisition Time"); - MEDCORE_EXPORT const Key Comments("Comments"); - MEDCORE_EXPORT const Key FilePaths("FilePaths", "File Paths"); - MEDCORE_EXPORT const Key Status("Status"); - MEDCORE_EXPORT const Key SequenceName("SequenceName", "Sequence Name"); - MEDCORE_EXPORT const Key Size("Size","Size",QVariant::UInt, false); - MEDCORE_EXPORT const Key VolumeUID("VolumeUID", "Volume UID"); - MEDCORE_EXPORT const Key Spacing("Spacing"); - MEDCORE_EXPORT const Key XSpacing("XSpacing", "X Spacing"); - MEDCORE_EXPORT const Key YSpacing("YSpacing", "Y Spacing"); - MEDCORE_EXPORT const Key ZSpacing("ZSpacing", "Z Spacing"); - MEDCORE_EXPORT const Key NumberOfComponents("NumberOfComponents", "Number Of Components"); - MEDCORE_EXPORT const Key ComponentType("ComponentType", "Component Type"); - MEDCORE_EXPORT const Key PixelType("PixelType", "Pixel Type"); - MEDCORE_EXPORT const Key medDataType("medDataType", "Dtk Data Type"); - MEDCORE_EXPORT const Key PreferredDataReader("PreferredDataReader", "Preferred Data Reader"); - MEDCORE_EXPORT const Key ImageID("ImageID"); - MEDCORE_EXPORT const Key ThumbnailPath("ThumbnailPath", "Thumbnail Path"); - MEDCORE_EXPORT const Key AcquisitionNumber("AcquisitionNumber", "Acquisition Number"); - - MEDCORE_EXPORT const Key PatientOrientation("PatientOrientation", "Patient Orientation"); - MEDCORE_EXPORT const Key PatientPosition("PatientPosition", "Patient Position"); - MEDCORE_EXPORT const Key ImageType("ImageType", "Image Type"); - - // Frame of reference - MEDCORE_EXPORT const Key FrameOfReferenceUID("FrameOfReferenceUID", "Frame of Reference UID"); - MEDCORE_EXPORT const Key PositionReferenceIndicator("PositionReferenceIndicator", "Position Reference Indicator"); - - // MR Image - MEDCORE_EXPORT const Key FlipAngle("FlipAngle", "Flip Angle"); - MEDCORE_EXPORT const Key EchoTime("EchoTime", "Echo Time"); - MEDCORE_EXPORT const Key RepetitionTime("RepetitionTime", "Repetition Time"); - - // CT Image - - // EXPORT EXTRA DATA TO ATTACHED FILE - // MEDCORE_EXPORT const Key Toolbox("Toolbox", "Toolbox used to process image"); - // MEDCORE_EXPORT const Key OriginalDataUID("OriginalDataUID", "UID of original data used to generate new data"); - // MEDCORE_EXPORT const Key OriginalDataDesc("OriginalDataDesc", "Description of original data used to generate new data"); - // MEDCORE_EXPORT const Key FileMetadataPath("FileMetadataPath", "Path to attached metadata file"); - MEDCORE_EXPORT const Key KVP("KVP", "kVp", QVariant::UInt); -}; +#include +#define CHAPTER_NAME "chapterName" +#define CHAPTER_KEYS "keys" +#define KEY_NAME "name" +#define KEY_LABEL "label" +#define KEY_TAG "tag" +#define KEY_MEDKEY_PIVOT "medKey" +#define KEY_TYPE "type" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +medMetaDataKeys *medMetaDataKeys::s_instance = nullptr; + + +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////// Static public part /////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +medMetaDataKeys *medMetaDataKeys::instance() +{ + if (!s_instance) + { + s_instance = new medMetaDataKeys(); + s_instance->m_path = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/" + QCoreApplication::organizationName() + "/" + QCoreApplication::applicationName() + "/keysDictionnaries"; + s_instance->fetchChapterDirectory(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/" + QCoreApplication::organizationName() + "/" + QCoreApplication::applicationName() + "/keysDictionnaries"); + } + return s_instance; +} + + +bool medMetaDataKeys::registerKey(Key2 key, QString chapter) +{ + return medMetaDataKeys::instance()->registerKeyInternal(key, chapter); +} + +bool medMetaDataKeys::addKeyToChapter(Key2 key, QString chapter) +{ + return medMetaDataKeys::instance()->addKeyToChapterInternal(key, chapter); +} + +bool medMetaDataKeys::addKeyByTagToChapter(QString tag, QString keyLabel, QString keyName, QString chapter) +{ + if (keyName.isEmpty()) + { + keyName = tag; + } + else + { + if (keyLabel.isEmpty()) keyLabel = keyName; + } + + Key2 key(keyName, keyLabel, tag); + return medMetaDataKeys::instance()->addKeyToChapterInternal(key, chapter); + +} + +Key2 medMetaDataKeys::key(QString word) +{ + return medMetaDataKeys::instance()->keyInternal(word); +} + +Key2 medMetaDataKeys::keyFromPivot(QString pivot) +{ + return medMetaDataKeys::instance()->keyFromPivotInternal(pivot); +} + +Key2 medMetaDataKeys::keyFromName(QString keyName, QString chapter) +{ + return medMetaDataKeys::instance()->keyFromNameInternal(keyName, chapter); +} + +Key2 medMetaDataKeys::keyFromTag(QString keyTag, QString chapter) +{ + return medMetaDataKeys::instance()->keyFromTagInternal(keyTag, chapter); +} + +QString medMetaDataKeys::pivot(QString keyName, QString chapter) +{ + return medMetaDataKeys::instance()->pivotInternal(keyName, chapter); +} + +bool medMetaDataKeys::keyExist(Key2 const & key) +{ + return medMetaDataKeys::instance()->keyExistInternal(key); +} + +QString medMetaDataKeys::getValue(Key2 &key, QMap metaDataList) +{ + QString valRes; + + auto keys = metaDataList.keys(); + + if (keys.contains(key.name())) + { + valRes = metaDataList[key.name()]; + } + else if (keys.contains(key.medPivot())) + { + valRes = metaDataList[key.medPivot()]; + } + else if(keys.contains(key.tag())) + { + valRes = metaDataList[key.tag()]; + } + + return valRes; +} + + + +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////// Private part ///////////////////////////////////////////////////////// +// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +medMetaDataKeys::medMetaDataKeys() +{ + m_saveSheduler.setSingleShot(true); + m_saveSheduler.callOnTimeout(this, &medMetaDataKeys::delegateWriting); +} + +// //////////////////////////////////////////////////////////////////////////// +// read part from file system +bool medMetaDataKeys::fetchChapterDirectory(QString path) +{ + bool bRes = false; + qDebug() << "medMetaDataKeys: Begin parsing metadata key directory to build a dictionary into : " << path; + + QDirIterator it(path, QStringList() << "*.json", QDir::Files); + while (it.hasNext()) + { + QString filePath = it.next(); + QFile file(filePath); + file.open(QFile::ReadOnly); + QString chapterName = loadChapter(file.readAll()); + if (!chapterName.isEmpty()) + { + m_chapterToFileMap[chapterName] << filePath; + } + else + { + qDebug() << "File : " << filePath << " is a malformed json key file"; + } + + } + + qDebug() << "medMetaDataKeys: Parsing ended into : " << path; + return bRes; +} + +QString medMetaDataKeys::loadChapter(QByteArray chapter) +{ + bool bRes = false; + QString chapterRes; + + QJsonDocument chapterDoc = QJsonDocument::fromJson(chapter); + if (chapterDoc.isObject()) + { + QJsonObject chapterObj = chapterDoc.object(); + if (chapterObj.contains(CHAPTER_NAME) && chapterObj[CHAPTER_NAME].isString() && + chapterObj.contains(CHAPTER_KEYS) && chapterObj[CHAPTER_KEYS].isArray()) + { + QString chapterName = chapterObj[CHAPTER_NAME].toString().trimmed(); + chapterRes = chapterName; + QJsonArray keys = chapterObj[CHAPTER_KEYS].toArray(); + if (!chapterName.isEmpty() && !keys.isEmpty()) + { + for (auto entry : keys) + { + Key2 keyOut; + if (entry.isObject()) + { + QJsonObject key = entry.toObject(); + if (readKey(key, keyOut)) + { + bRes = true; + } + else + { + qDebug() << "Unable to read a key in " << chapterName; + } + + registerKey(keyOut, chapterName); + } + } + } + else + { + qDebug() << "Both, " << CHAPTER_KEYS << " and " << CHAPTER_NAME << " must be not empty values " << chapterName; + } + } + else + { + qDebug() << "Both, " << CHAPTER_KEYS << " and " << CHAPTER_NAME << "are mandatories keys"; + } + } + + return bRes ? chapterRes : ""; +} + + +bool medMetaDataKeys::readKey(QJsonObject keyAsJson, Key2 & key) +{ + bool bRes = false; + + QString name; + QString label; + QString tag; + QString medKey; + QVariant::Type type = QVariant::Type::Invalid; + + if (keyAsJson.contains(KEY_NAME) && keyAsJson[KEY_NAME].isString()) + { + name = keyAsJson[KEY_NAME].toString(); + bRes = !name.trimmed().isEmpty(); + + if (bRes) + { + if (keyAsJson.contains(KEY_LABEL) && keyAsJson[KEY_LABEL].isString()) + { + label = keyAsJson[KEY_LABEL].toString().trimmed(); + } + if (keyAsJson.contains(KEY_TAG) && keyAsJson[KEY_TAG].isString()) + { + tag = keyAsJson[KEY_TAG].toString().trimmed(); + } + if (keyAsJson.contains(KEY_MEDKEY_PIVOT) && keyAsJson[KEY_MEDKEY_PIVOT].isString()) + { + medKey = keyAsJson[KEY_MEDKEY_PIVOT].toString().trimmed(); + } + if (keyAsJson.contains(KEY_TYPE) && keyAsJson[KEY_TYPE].isString()) + { + type = QVariant::nameToType(keyAsJson[KEY_TYPE].toString().toUtf8().data()); + } + + key = Key2(name, label, tag, medKey, type); + } + else + { + qDebug() << "Key as invalid format. Name must be a non empty string."; + } + + } + else + { + qDebug() << "Key as invalid format. Name is mandatory."; + } + + return bRes; +} + + +// //////////////////////////////////////////////////////////////////////////// +// write part to file system +bool medMetaDataKeys::updateChapterDirectory(QString path) +{ + bool bRes = true; + + + for (QString const & chapter : m_chaptersToUpdate) + { + QString filePath; + if (m_chapterToFileMap.contains(chapter) && m_chapterToFileMap[chapter].back().startsWith(path)) + { + filePath = m_chapterToFileMap[chapter].back(); + } + else + { + filePath = path + '/' + chapter + ".json"; + m_chapterToFileMap[chapter].push_back(filePath); + } + QJsonDocument chapterJson; + if (writeChapter(chapter, chapterJson)) + { + QFile file(filePath); + if (file.open(QFile::ReadWrite)) + { + bRes = bRes && file.write(chapterJson.toJson()) != -1; + } + else + { + qDebug() << "meta data system can't create or update " << filePath; + } + } + } + + return bRes; +} + +bool medMetaDataKeys::writeChapter(QString chapterName, QJsonDocument &chapter) +{ + bool bRes = false; + + + if (m_medKeyByChapterMap.contains(chapterName)) + { + bRes = true; + QJsonArray jsonKeys; + for (auto & key : *m_medKeyByChapterMap[chapterName]) + { + QJsonObject keyJson; + if (writeKey(key, keyJson)) + { + jsonKeys.push_back(keyJson); + } + else + { + qDebug() << "An invalid key is found in chapter " << chapterName; + } + } + + QJsonObject chapterObject; + chapterObject.insert(CHAPTER_NAME, chapterName); + chapterObject.insert(CHAPTER_KEYS, jsonKeys); + chapter.setObject(chapterObject); + } + + return bRes; +} + +bool medMetaDataKeys::writeKey(Key2 const & key, QJsonObject & keyAsJson) +{ + bool bRes = true; + + if (!key.name().isEmpty()) + { + keyAsJson.insert(KEY_NAME, key.name().trimmed()); + if (key.label().trimmed().isEmpty()) + { + keyAsJson.insert(KEY_LABEL, key.name().trimmed()); + } + else + { + keyAsJson.insert(KEY_LABEL, key.label().trimmed()); + } + if (!key.tag().trimmed().isEmpty()) + { + keyAsJson.insert(KEY_TAG, key.tag().trimmed()); + } + if (key.medPivot().trimmed().isEmpty()) + { + keyAsJson.insert(KEY_MEDKEY_PIVOT, key.name().trimmed().toLower()); + } + else + { + keyAsJson.insert(KEY_MEDKEY_PIVOT, key.medPivot().trimmed().toLower()); + } + //if (key.type() != QVariant::Type::Invalid) + //{ + // keyAsJson.insert(KEY_TYPE, key.type().typeName()); + //} + } + else + { + bRes = false; + qDebug() << "Try to save an invalid key."; + } + + return bRes; +} + + + + +// //////////////////////////////////////////////////////////////////////////// +// Internal part of public static functions +bool medMetaDataKeys::registerKeyInternal(Key2 &key, QString &chapter) +{ + bool bRes = false; + if (m_medKeyByChapterMap[chapter] == nullptr) m_medKeyByChapterMap[chapter] = new QList(); + if (!m_medKeyByChapterMap[chapter]->contains(key.name())) + { + + if (key.medPivot() == "") + { + // Here key don't have a medInria pivot + // We try to find an other similar key to determine the pivot + auto name = key.name().trimmed().toLower(); + for (auto keysOfChapter : m_medKeyByChapterMap.values()) + { + for (auto aKey : *keysOfChapter) + { + if (aKey.name().trimmed().toLower() == name) + { + key.setMedPivot(aKey.medPivot()); // + break; + } + } + } + + if (key.medPivot() == "") + { + // No other similar key exist then we derivate the pivot from the name + key.setMedPivot(key.name()); + } + } + + // We wand medInria key force to lowercase and without useless spaces characters + key.setMedPivot(key.medPivot().trimmed().toLower()); + + m_medKeyByChapterMap[chapter]->push_back(key); + if (m_medKeyByPivotMap[key.medPivot()] == nullptr) m_medKeyByPivotMap[key.medPivot()] = new QList(); + m_medKeyByPivotMap[key.medPivot()]->push_back(&m_medKeyByChapterMap[chapter]->last()); + + bRes = true; + } + + return bRes; +} + +bool medMetaDataKeys::addKeyToChapterInternal(Key2 &key, QString &chapter) +{ + bool bRes = true; + + m_medKeyByChapterMap[chapter]; + + bool needUpdate = false; + + bool keyMedPivotStrong; + bool keyTagStrong; + bool keyNameStrong; + bool keyLabelStrong; + + strongKeyEval(key, keyTagStrong, keyMedPivotStrong, keyNameStrong, keyLabelStrong); + + if (m_medKeyByChapterMap[chapter] == nullptr) + { + m_medKeyByChapterMap[chapter] = new QList(); + m_medKeyByChapterMap[chapter]->push_back(key); + needUpdate = true; + } + else + { + auto * keysVector = m_medKeyByChapterMap[chapter]; + QVector oldKeysByTag; + QVector oldKeysByPivot; + QVector oldKeysByName; + + for (auto oldKey : *keysVector) + { + if (keyTagStrong) + { + if (oldKey.tag() == key.tag()) + { + oldKeysByTag.push_back(&oldKey); + } + } + if (keyMedPivotStrong) + { + if (oldKey.medPivot() == key.medPivot()) + { + oldKeysByPivot.push_back(&oldKey); + } + } + if (keyNameStrong) + { + if (oldKey.name() == key.name()) + { + oldKeysByName.push_back(&oldKey); + } + } + } + + if (oldKeysByTag.isEmpty() && oldKeysByPivot.isEmpty() && oldKeysByName.isEmpty()) + { + m_medKeyByChapterMap[chapter]->push_back(key); + needUpdate = true; + // m_medKeyByPivotMap.insertMulti(key.medPivot(), &m_medKeyByChapterMap[chapter].last()); + } + else + { + needUpdate = updateKey(key, { &oldKeysByTag , &oldKeysByPivot , &oldKeysByName }); + //m_chaptersToUpdate << m_chapterToFileMap[chapter]; + } + //scheduleUpdate(chapter); + } + + if (needUpdate) + { + scheduleUpdate(chapter); + } + + return bRes; +} + +bool medMetaDataKeys::updateKey(Key2 &key, QList*> oldKeysLists) +{ + bool bRes = false; + bool keyMedPivotStrong; + bool keyTagStrong; + bool keyNameStrong; + bool keyLabelStrong; + + strongKeyEval(key, keyTagStrong, keyMedPivotStrong, keyNameStrong, keyLabelStrong); + + for (auto oldKeys : oldKeysLists) + { + for (auto *oldKey : *oldKeys) + { + bool oldKeyMedPivotStrong; + bool oldKeyTagStrong; + bool oldKeyNameStrong; + bool oldKeyLabelStrong; + + strongKeyEval(*oldKey, oldKeyTagStrong, oldKeyMedPivotStrong, oldKeyNameStrong, oldKeyLabelStrong); + + if (!oldKeyTagStrong && keyTagStrong) { bRes = true; oldKey->setTag(key.tag()); } + if (!oldKeyMedPivotStrong && keyMedPivotStrong) { bRes = true; oldKey->setMedPivot(key.medPivot()); } + if (!oldKeyNameStrong && keyNameStrong) { bRes = true; oldKey->setName(key.name()); } + if (!oldKeyLabelStrong && keyLabelStrong) { bRes = true; oldKey->setLabel(key.label()); } + } + } + + return bRes; +} + +void medMetaDataKeys::strongKeyEval(Key2 const & key, bool &keyTagStrong, bool &keyMedPivotStrong, bool &keyNameStrong, bool &keyLabelStrong) +{ + keyMedPivotStrong = !key.medPivot().isEmpty() && key.medPivot() != key.name() && key.medPivot() != key.tag(); + keyTagStrong = !key.tag().isEmpty(); + keyNameStrong = key.name() != key.tag(); + keyLabelStrong = !key.label().isEmpty() && key.label() != key.name(); +} + + +Key2 medMetaDataKeys::keyInternal(QString &word) +{ + Key2 keyRes; + + + keyRes = keyFromPivotInternal(word); + if (!keyRes.isValid()) + { + for (QString chapter : m_chapterToFileMap.keys()) + { + keyRes = keyFromNameInternal(word, chapter); + if (keyRes.isValid()) + { + break; + } + } + } + + if (!keyRes.isValid()) + { + for (QString chapter : m_chapterToFileMap.keys()) + { + keyRes = keyFromTagInternal(word, chapter); + if (keyRes.isValid()) + { + break; + } + } + } + + return keyRes; +} + +Key2 medMetaDataKeys::keyFromPivotInternal(QString & pivot) +{ + Key2 keyRes; + + pivot = pivot.toLower().trimmed(); + + if (m_medKeyByPivotMap.contains(pivot)) + { + keyRes = *m_medKeyByPivotMap.value(pivot)->first(); + } + + return keyRes; +} + +Key2 medMetaDataKeys::keyFromNameInternal(QString &keyName, QString chapter) +{ + Key2 keyRes; + + int pos = -1; + if (m_medKeyByChapterMap.contains(chapter)) + { + QList* keys = m_medKeyByChapterMap[chapter]; + pos = keys->indexOf(keyName); + if (pos != -1) + { + keyRes = keys->at(pos); + } + } + + return keyRes; +} + +Key2 medMetaDataKeys::keyFromTagInternal(QString & keyTag, QString chapter) +{ + Key2 keyRes; + + int pos = -1; + if (m_medKeyByChapterMap.contains(chapter)) + { + QList* keys = m_medKeyByChapterMap[chapter]; + for (auto & key : *keys) + { + if (key.tag() == keyTag) + { + keyRes = key; + break; + } + } + } + + return keyRes; +} + + +QString medMetaDataKeys::pivotInternal(QString &keyName, QString chapter) +{ + return keyFromName(keyName, chapter).medPivot(); +} + +bool medMetaDataKeys::keyExistInternal(Key2 const & key) +{ + return m_medKeyByPivotMap.contains(key.medPivot()); +} + +void medMetaDataKeys::scheduleUpdate(QString &chapter) +{ + m_mutex.lock(); + m_saveSheduler.stop(); + if (!m_chaptersToUpdate.contains(chapter)) + { + m_chaptersToUpdate.push_back(chapter); + } + m_mutex.unlock(); + m_saveSheduler.start(5000); +} + +void medMetaDataKeys::delegateWriting() +{ + this->m_mutex.lock(); + if (updateChapterDirectory(this->m_path)) + { + this->m_chaptersToUpdate.clear(); + } + else + { + qDebug() << "medMetaDataKeys: Unable to update chapters at path " << this->m_path; + } + this->m_mutex.unlock(); +} + + +bool operator==(Key2 const & k1, Key2 const & k2) +{ + bool bRes = k1.m_medPivot.isEmpty() || k2.m_medPivot.isEmpty() || k1.m_medPivot == k2.m_medPivot; + + bRes = bRes && k1.m_name == k2.m_name; + + return bRes; +} + +bool operator==(QString const & s, Key2 const & k) +{ + return s == k.m_name; +} + +bool operator==(Key2 const & k, QString const & s) +{ + return s == k.m_name; +} \ No newline at end of file diff --git a/src/layers/medCore/legacy/data/medMetaDataKeys.h b/src/layers/medCore/legacy/data/medMetaDataKeys.h index cbe49fb20f..4b8c6c6fbd 100644 --- a/src/layers/medCore/legacy/data/medMetaDataKeys.h +++ b/src/layers/medCore/legacy/data/medMetaDataKeys.h @@ -13,166 +13,167 @@ =========================================================================*/ #include -#include -namespace medMetaDataKeys +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +using keyConverter = bool(*)(QVariant const & inputData, QVariant & outputData); + +class MEDCORE_EXPORT Key2 { - /** - * @class Key - * @author John Stark, modified by papadop - * It allows compile-time verification that the keyword is correct. - */ +public: + Key2() = default; + Key2(QString const & name, QString const & label = "", QString const & tag = "", QString const & medKey = "", QVariant::Type type = QVariant::String) : + m_name(name), m_label(label), m_tag(tag), m_medPivot(medKey), m_type(type) + { + if (label == "") m_label = name; + } + + Key2(Key2 const & key) + { + m_name = key.m_name; + m_label = key.m_label; + m_tag = key.m_tag; + m_medPivot = key.m_medPivot; + m_type = key.m_type; + } + + Key2(Key2 const && key) noexcept : - class MEDCORE_EXPORT Key + m_name(std::move(key.m_name)), + m_label(std::move(key.m_label)), + m_tag(std::move(key.m_tag)), + m_medPivot(std::move(key.m_medPivot)), + m_type(std::move(key.m_type)) + {} + + ~Key2() { } + + Key2& operator=(Key2 && k) noexcept + { + this->m_name = k.m_name; + this->m_label = k.m_label; + this->m_tag = k.m_tag; + this->m_medPivot = k.m_medPivot; + this->m_type = k.m_type; + + return *this; + } + + Key2& operator=(Key2 const & k) { - public: - typedef std::vector Registery; - - Key(const char* name, const char* label="", - QVariant::Type type=QVariant::String, bool isEditable = true): KEY(name), LABEL(label), TYPE(type), ISEDITABLE(isEditable) - { - if(QString(label)=="") LABEL=QString(name); - registery.push_back(this); - } - - ~Key() { } - - const QString& key() const { return KEY; } - const QString& label() const { return LABEL; } - const QVariant::Type& type() const { return TYPE; } - bool isEditable() const { return ISEDITABLE; } - - bool is_set_in(const medAbstractData *data) const { return data->hasMetaData(KEY) ; } - - const QStringList getValues(const medAbstractData *data) const { return data->metaDataValues(KEY); } - - const QString getFirstValue(const medAbstractData *data, const QString defaultValue=QString("")) const - { - return data->hasMetaData(KEY) ? data->metaDataValues(KEY)[0] : defaultValue; - } - - void add(medAbstractData* d,const QStringList& values) const { d->addMetaData(KEY,values); } - void add(medAbstractData* d,const QString& value) const { d->addMetaData(KEY,value); } - void set(medAbstractData* d,const QStringList& values) const { d->setMetaData(KEY,values); } - void set(medAbstractData* d,const QString& value) const { d->setMetaData(KEY,value); } - - static const Registery& all() { return registery; } - - bool operator==(const Key& other){ return ( this->key() == other.key() ); } - - static const Key* fromKeyName(const char* name) - { - std::vector::iterator it; - for ( it=registery.begin() ; it < registery.end(); it++ ) - { - if( (*it)->key() == name ) - return *it; - } - return nullptr; - } - - private: - - static Registery registery; - - const QString KEY; - QString LABEL; - QVariant::Type TYPE; - bool ISEDITABLE; - }; - - - /** Define the actual keys to use */ - - extern MEDCORE_EXPORT const Key TransferSyntaxUID; - extern MEDCORE_EXPORT const Key ContainsBasicInfo; - - // PATIENT - extern MEDCORE_EXPORT const Key PatientID; - extern MEDCORE_EXPORT const Key PatientName; - extern MEDCORE_EXPORT const Key Age; - extern MEDCORE_EXPORT const Key BirthDate; - extern MEDCORE_EXPORT const Key Gender; - extern MEDCORE_EXPORT const Key Description; - - // STUDY - extern MEDCORE_EXPORT const Key StudyID; - extern MEDCORE_EXPORT const Key StudyInstanceUID; - extern MEDCORE_EXPORT const Key StudyDescription; - extern MEDCORE_EXPORT const Key Institution; - extern MEDCORE_EXPORT const Key Referee; - extern MEDCORE_EXPORT const Key StudyDate; - extern MEDCORE_EXPORT const Key StudyTime; - - // SERIES - extern MEDCORE_EXPORT const Key SeriesID; - extern MEDCORE_EXPORT const Key SeriesInstanceUID; - extern MEDCORE_EXPORT const Key SeriesStoreId; - extern MEDCORE_EXPORT const Key SeriesNumber; - extern MEDCORE_EXPORT const Key Modality; - extern MEDCORE_EXPORT const Key Performer; - extern MEDCORE_EXPORT const Key Report; - extern MEDCORE_EXPORT const Key Protocol; - extern MEDCORE_EXPORT const Key SeriesDescription; - extern MEDCORE_EXPORT const Key SeriesDate; - extern MEDCORE_EXPORT const Key SeriesTime; - extern MEDCORE_EXPORT const Key SeriesThumbnail; - - // IMAGE - extern MEDCORE_EXPORT const Key SOPInstanceUID; - extern MEDCORE_EXPORT const Key Columns; - extern MEDCORE_EXPORT const Key Rows; - extern MEDCORE_EXPORT const Key Dimensions; - extern MEDCORE_EXPORT const Key NumberOfDimensions; - extern MEDCORE_EXPORT const Key Orientation; - extern MEDCORE_EXPORT const Key Origin; - extern MEDCORE_EXPORT const Key SliceThickness; - extern MEDCORE_EXPORT const Key PatientOrientation; - extern MEDCORE_EXPORT const Key PatientPosition; - extern MEDCORE_EXPORT const Key ImportationDate; - extern MEDCORE_EXPORT const Key AcquisitionDate; - extern MEDCORE_EXPORT const Key AcquisitionTime; - extern MEDCORE_EXPORT const Key Comments; - extern MEDCORE_EXPORT const Key FilePaths; - extern MEDCORE_EXPORT const Key Status; - extern MEDCORE_EXPORT const Key SequenceName; - extern MEDCORE_EXPORT const Key Size; - extern MEDCORE_EXPORT const Key VolumeUID; - extern MEDCORE_EXPORT const Key Spacing; - extern MEDCORE_EXPORT const Key XSpacing; - extern MEDCORE_EXPORT const Key YSpacing; - extern MEDCORE_EXPORT const Key ZSpacing; - extern MEDCORE_EXPORT const Key NumberOfComponents; - extern MEDCORE_EXPORT const Key ComponentType; - extern MEDCORE_EXPORT const Key PixelType; - extern MEDCORE_EXPORT const Key medDataType; - extern MEDCORE_EXPORT const Key PreferredDataReader; - extern MEDCORE_EXPORT const Key ImageID; - extern MEDCORE_EXPORT const Key ImageType; - extern MEDCORE_EXPORT const Key ThumbnailPath; - extern MEDCORE_EXPORT const Key AcquisitionNumber; - - // Frame of reference - extern MEDCORE_EXPORT const Key FrameOfReferenceUID; - extern MEDCORE_EXPORT const Key PositionReferenceIndicator; - - // EQUIPEMENT - extern MEDCORE_EXPORT const Key Manufacturer; - - // CT - extern MEDCORE_EXPORT const Key KVP; - - // MR Image - - // EXPORT EXTRA DATA TO ATTACHED FILE - // extern MEDCORE_EXPORT const Key Toolbox; - // extern MEDCORE_EXPORT const Key OriginalDataUID; - // extern MEDCORE_EXPORT const Key OriginalDataDesc; - // extern MEDCORE_EXPORT const Key FileMetadataPath; - extern MEDCORE_EXPORT const Key FlipAngle; - extern MEDCORE_EXPORT const Key EchoTime; - extern MEDCORE_EXPORT const Key RepetitionTime; + this->m_name = k.m_name; + this->m_label = k.m_label; + this->m_tag = k.m_tag; + this->m_medPivot = k.m_medPivot; + this->m_type = k.m_type; + + return *this; + } + + friend MEDCORE_EXPORT bool operator==(Key2 const & k1, Key2 const & k2); + friend MEDCORE_EXPORT bool operator==(QString const & s, Key2 const & k); + friend MEDCORE_EXPORT bool operator==(Key2 const & k, QString const & s); + + operator QString() const { return m_name; } + //operator char const *() const { return m_name.toUtf8(); }; + + const QString& name() const { return m_name; } + const QString& label() const { return m_label; } + const QString& tag() const { return m_tag; } + const QString& medPivot() const { return m_medPivot; } + const QVariant::Type& type() const { return m_type; } + + void setName(QString name) { m_name = name; } + void setTag(QString tag) { m_tag = tag; } + void setMedPivot(QString pivot) { m_medPivot = pivot; } + void setLabel(QString label) { m_label = label; } + + bool isValid() { return ! m_medPivot.isEmpty(); } + +private: + + QString m_name; + QString m_label; + QString m_tag; + QString m_medPivot; + QVariant::Type m_type; }; + +class MEDCORE_EXPORT medMetaDataKeys : public QObject +{ + Q_OBJECT +public: + ~medMetaDataKeys() = default; + + static medMetaDataKeys * instance(); + + static bool registerKey(Key2 key, QString chapter = "default"); + static bool addKeyToChapter(Key2 key, QString chapter = "default"); + static bool addKeyByTagToChapter(QString tag, QString keyLabel = "", QString keyName = "", QString chapter = "default"); + + static Key2 key(QString word); + static Key2 keyFromPivot(QString pivot); + static Key2 keyFromName(QString keyName, QString chapter = ""); + static Key2 keyFromTag(QString keyTag, QString chapter = ""); + static QString pivot(QString keyName, QString chapter = ""); + + static bool keyExist(Key2 const & key); + + static QString getValue(Key2 &key, QMap metaDataList); +private: + medMetaDataKeys(); + + bool fetchChapterDirectory(QString path); + QString loadChapter(QByteArray chapter); //return chapter name or empty if it fails + bool readKey(QJsonObject keyAsJson, Key2 &key); + + bool updateChapterDirectory(QString path); + bool writeChapter(QString chapterName, QJsonDocument &chapter); + bool writeKey(Key2 const &key, QJsonObject &keyAsJson); + + + bool registerKeyInternal(Key2 &key, QString& chapter); + bool addKeyToChapterInternal(Key2 &key, QString &chapter); + + bool updateKey(Key2 &key, QList*> oldKeysLists); + + void strongKeyEval(Key2 const & key, bool &keyTagStrong, bool &keyMedPivotStrong, bool &keyNameStrong, bool &keyLabelStrong); + + Key2 keyInternal(QString &word); + Key2 keyFromPivotInternal(QString &pivot); + Key2 keyFromNameInternal(QString &keyName, QString chapter = ""); + Key2 keyFromTagInternal(QString &keyTag, QString chapter = ""); + QString pivotInternal(QString &keyName, QString chapter = ""); + + bool keyExistInternal(Key2 const & key); + + void scheduleUpdate(QString &chapter); + void delegateWriting(); + +private: + static medMetaDataKeys * s_instance; + + QString m_path; + + QMap*> m_medKeyByPivotMap; + QMap*> m_medKeyByChapterMap; + QMap /*file name*/ > m_chapterToFileMap; + + QVector m_chaptersToUpdate; + QTimer m_saveSheduler; + QMutex m_mutex; +}; diff --git a/src/layers/medCore/legacy/database/medDataIndex.h b/src/layers/medCore/legacy/database/medDataIndex.h index 740731a0d8..92cb242244 100644 --- a/src/layers/medCore/legacy/database/medDataIndex.h +++ b/src/layers/medCore/legacy/database/medDataIndex.h @@ -100,6 +100,7 @@ class MEDCORE_EXPORT medDataIndex int m_seriesId; QStringList m_uriAsList; QString m_humanRedableUri; + QList m_childrens; }; // ///////////////////////////////////////////////////////////////// diff --git a/src/layers/medCore/legacy/database/medDataManager.cpp b/src/layers/medCore/legacy/database/medDataManager.cpp index a7bde270e2..c529593839 100644 --- a/src/layers/medCore/legacy/database/medDataManager.cpp +++ b/src/layers/medCore/legacy/database/medDataManager.cpp @@ -44,13 +44,20 @@ medDataManager *medDataManager::instance() return s_instance; } -medAbstractData *medDataManager::retrieveData(const medDataIndex &index) +medAbstractData* medDataManager::retrieveData(const medDataIndex &index) { Q_D(medDataManager); - + return medDataHub::instance()->getData(index); } +QList medDataManager::retrieveDataList(const medDataIndex &index) +{ + Q_D(medDataManager); + + return medDataHub::instance()->getDataList(index); +} + void medDataManager::loadData(const medDataIndex &index) {} // //////////////////////////////////////////////////////////////////////// diff --git a/src/layers/medCore/legacy/database/medDataManager.h b/src/layers/medCore/legacy/database/medDataManager.h index 67b7746d97..25a9f58383 100644 --- a/src/layers/medCore/legacy/database/medDataManager.h +++ b/src/layers/medCore/legacy/database/medDataManager.h @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -32,7 +33,8 @@ class MEDCORE_EXPORT medDataManager : public QObject public: static medDataManager * instance(); - medAbstractData* retrieveData(const medDataIndex& index); + medAbstractData* retrieveData(const medDataIndex &index); + QList retrieveDataList(const medDataIndex& index); void loadData(const medDataIndex &index); QHash getPossibleWriters(medAbstractData* data); diff --git a/src/layers/medCore/legacy/gui/medAbstractWorkspaceLegacy.cpp b/src/layers/medCore/legacy/gui/medAbstractWorkspaceLegacy.cpp index 06b8a6714c..fec6444832 100644 --- a/src/layers/medCore/legacy/gui/medAbstractWorkspaceLegacy.cpp +++ b/src/layers/medCore/legacy/gui/medAbstractWorkspaceLegacy.cpp @@ -355,7 +355,10 @@ void medAbstractWorkspaceLegacy::updateLayersToolBox() QWidget *layerWidget = new QWidget; layerWidget->setObjectName("layerWidget"); - QString name = medMetaDataKeys::SeriesDescription.getFirstValue(data,"no name"); + //QString name = data->fecthMetaData("SeriesDescription")); + QString name = data->fecthMetaData("seriesdescription"); + + if (name.isEmpty()) name = "no name"; QHBoxLayout* layout = new QHBoxLayout(layerWidget); layout->setContentsMargins(0,0,5,0); diff --git a/src/layers/medCore/legacy/gui/settingsWidgets/medStartupSettingsWidget.cpp b/src/layers/medCore/legacy/gui/settingsWidgets/medStartupSettingsWidget.cpp index f04b3070b8..693556334c 100644 --- a/src/layers/medCore/legacy/gui/settingsWidgets/medStartupSettingsWidget.cpp +++ b/src/layers/medCore/legacy/gui/settingsWidgets/medStartupSettingsWidget.cpp @@ -18,6 +18,8 @@ #include #include +#include +#include #include class medStartupSettingsWidgetPrivate diff --git a/src/layers/medCore/legacy/gui/settingsWidgets/medStartupSettingsWidget.h b/src/layers/medCore/legacy/gui/settingsWidgets/medStartupSettingsWidget.h index efd8ebfbbe..18e88951ff 100644 --- a/src/layers/medCore/legacy/gui/settingsWidgets/medStartupSettingsWidget.h +++ b/src/layers/medCore/legacy/gui/settingsWidgets/medStartupSettingsWidget.h @@ -17,8 +17,6 @@ #include #include -#include -#include #include #include #include diff --git a/src/layers/medCore/legacy/gui/toolboxes/medRegistrationSelectorToolBox.cpp b/src/layers/medCore/legacy/gui/toolboxes/medRegistrationSelectorToolBox.cpp index 6ade817b41..46b4bca167 100644 --- a/src/layers/medCore/legacy/gui/toolboxes/medRegistrationSelectorToolBox.cpp +++ b/src/layers/medCore/legacy/gui/toolboxes/medRegistrationSelectorToolBox.cpp @@ -304,7 +304,7 @@ void medRegistrationSelectorToolBox::handleOutput(typeOfOperation type, QString QString newDescription = ""; if(d->movingData) { - newDescription = d->movingData->metadata(medMetaDataKeys::SeriesDescription.key()); + newDescription = d->movingData->fecthMetaData("SeriesDescription"); } if (type==algorithm || type==redo) @@ -347,10 +347,10 @@ void medRegistrationSelectorToolBox::handleOutput(typeOfOperation type, QString output->addProperty(property,d->fixedData->propertyValues(property)); } - output->setMetaData(medMetaDataKeys::SeriesDescription.key(), newDescription); + output->setMetaData(medMetaDataKeys::key("SeriesDescription"), newDescription); QString generatedID = QUuid::createUuid().toString().replace("{","").replace("}",""); - output->setMetaData ( medMetaDataKeys::SeriesID.key(), generatedID ); + output->setMetaData ( medMetaDataKeys::key("SeriesID"), generatedID ); if (type==algorithm) medDataManager::instance()->importData(output); diff --git a/src/layers/medCore/legacy/gui/viewContainers/medDataLoadThread.cpp b/src/layers/medCore/legacy/gui/viewContainers/medDataLoadThread.cpp index 0534f1e5c1..765f2464da 100644 --- a/src/layers/medCore/legacy/gui/viewContainers/medDataLoadThread.cpp +++ b/src/layers/medCore/legacy/gui/viewContainers/medDataLoadThread.cpp @@ -15,26 +15,72 @@ #include +#include +#include #include #include -medDataLoadThread::medDataLoadThread(medDataIndex const & index, medViewContainer * parent) : m_index(index), m_parent(parent) -{ - connect(this, SIGNAL(dataReady(medAbstractData*)), m_parent, SLOT(addData(medAbstractData *)) ); -} -medDataLoadThread::~medDataLoadThread() +medDataLoadThread::medDataLoadThread(QList const & index, QList const & urls, medViewContainer *parent) : m_indexList(index), m_urlList(urls), m_parent(parent) { + connect(this, SIGNAL(dataReady(medAbstractData*)), m_parent, SLOT(addData(medAbstractData *))); } void medDataLoadThread::process() { - m_pAbsData = medDataManager::instance()->retrieveData(m_index); - if (m_pAbsData) + QStringList paths; + for (auto & url : m_urlList) + { + paths << url.toLocalFile(); + } + if (!paths.isEmpty()) + { + QStringList files; + QString path = computeRootPathOfListPath(paths, files); + m_indexList << fileSysPathToIndex(path, files); + } + + for (medDataIndex index : m_indexList) { - emit dataReady(m_pAbsData); + internalProcess(index, 3); } emit finished(); deleteLater(); } +void medDataLoadThread::internalProcess(medDataIndex &index, int deep) +{ + if (deep < 0) + { + //TODO ERROR + //TODO LOG + //TODO Notif + } + else + { + int type = medDataHub::instance()->getDataType(index); + if (type == DATATYPE_ROLE_DATASET || type == DATATYPE_ROLE_BOTH) + { + m_pAbsDataList << medDataManager::instance()->retrieveDataList(index); + for (auto absData : m_pAbsDataList) + { + if (absData) + { + emit dataReady(absData); + } + } + } + else if (type == DATATYPE_ROLE_FOLDER) + { + auto clidrenList = medDataManager::instance()->getSubData(index); + for (auto & child : clidrenList) + { + internalProcess(child, deep - 1); + } + } + else + { + //todo faire une notif d'erreur de non prise en charge + } + } +} diff --git a/src/layers/medCore/legacy/gui/viewContainers/medDataLoadThread.h b/src/layers/medCore/legacy/gui/viewContainers/medDataLoadThread.h index bf013c5f70..1c5a8347ba 100644 --- a/src/layers/medCore/legacy/gui/viewContainers/medDataLoadThread.h +++ b/src/layers/medCore/legacy/gui/viewContainers/medDataLoadThread.h @@ -16,19 +16,19 @@ #include #include +#include #include #include class medAbstractData; -class medDataLoadThread : public QObject //QThread +class medDataLoadThread : public QObject { Q_OBJECT public: - medDataLoadThread(medDataIndex const & index, medViewContainer *parent); -// medDataLoadThread(medDataIndex const & index); - virtual ~medDataLoadThread() override; + medDataLoadThread(QList const & index, QList const & urls, medViewContainer *parent); + virtual ~medDataLoadThread() override = default ; public slots: void process(); @@ -37,11 +37,15 @@ public slots: void finished(); void dataReady(medAbstractData *); -//protected: -// virtual void run() override; +private: + void internalProcess(medDataIndex &index, int deep); private: - medDataIndex m_index; + QList m_urlList; + QList m_indexList; medViewContainer *m_parent; - medAbstractData *m_pAbsData; + QList m_pAbsDataList; + QMap m_volumePathsMap; + QMap> m_volumeRelMap; + QString m_rootDir; }; diff --git a/src/layers/medCore/legacy/gui/viewContainers/medViewContainer.cpp b/src/layers/medCore/legacy/gui/viewContainers/medViewContainer.cpp index 456feea299..2fca622dbe 100644 --- a/src/layers/medCore/legacy/gui/viewContainers/medViewContainer.cpp +++ b/src/layers/medCore/legacy/gui/viewContainers/medViewContainer.cpp @@ -782,10 +782,7 @@ void medViewContainer::dropEvent(QDropEvent *event) { auto indexList = medDataIndex::readMimeDataMulti(mimeData); QList urlList = mimeData->urls(); - for (QUrl url : urlList) - { - indexList.append(fileSysPathToIndex(url.toLocalFile())); - } + if (d->mousseDragDropButton.testFlag(Qt::RightButton)) { QMenu *popupMenu = new QMenu(this); @@ -800,21 +797,15 @@ void medViewContainer::dropEvent(QDropEvent *event) popupMenu->exec(this->mapToGlobal(event->pos())); } else - { - for (auto &index : indexList) - { - //this->addData(index); - - QThread* thread = new QThread(this); - medDataLoadThread * pdataLoadThread = new medDataLoadThread(index, this); - thread->start(); - connect(thread, &QThread::started, pdataLoadThread, &medDataLoadThread::process); - connect(pdataLoadThread, &medDataLoadThread::finished, thread, &QThread::quit); - connect(pdataLoadThread, &medDataLoadThread::finished, pdataLoadThread, &medDataLoadThread::deleteLater); - connect(thread, &QThread::finished, thread, &QThread::deleteLater); - pdataLoadThread->moveToThread(thread); - - } + { + QThread* thread = new QThread(this); + medDataLoadThread * pdataLoadThread = new medDataLoadThread(indexList, urlList, this); + thread->start(); + connect(thread, &QThread::started, pdataLoadThread, &medDataLoadThread::process); + connect(pdataLoadThread, &medDataLoadThread::finished, thread, &QThread::quit); + connect(pdataLoadThread, &medDataLoadThread::finished, pdataLoadThread, &medDataLoadThread::deleteLater); + connect(thread, &QThread::finished, thread, &QThread::deleteLater); + pdataLoadThread->moveToThread(thread); this->setStyleSheet(d->defaultStyleSheet); if (d->selected) @@ -887,18 +878,6 @@ void medViewContainer::addData(medAbstractData *data) if(!data) return; - //addDataRunner * pAddDataRunner = new addDataRunner(); - //pAddDataRunner->view = this; - //pAddDataRunner->data = data; - //QThreadPool::globalInstance()->start(pAddDataRunner); - ////QThread* thread = new QThread(this); - ////medDataLoadThread * pdataLoadThread = new medDataLoadThread(index, this); - ////thread->start(); - ////connect(thread, &QThread::started, pdataLoadThread, &medDataLoadThread::process); - ////connect(pdataLoadThread, &medDataLoadThread::finished, thread, &QThread::quit); - ////connect(pdataLoadThread, &medDataLoadThread::finished, pdataLoadThread, &medDataLoadThread::deleteLater); - ////connect(thread, &QThread::finished, thread, &QThread::deleteLater); - ////pdataLoadThread->moveToThread(thread); if (prepareView()) { @@ -972,31 +951,9 @@ void medViewContainer::addData(medDataIndex const &index) } else { - qDebug() << "Type dataset or folder unkwon, try to load data as dataset for \"" << index.uri(); + qDebug() << "Type dataset or folder unkwon type, try to load data as dataset for \"" << index.uri(); } } - //else if (index.isValidForStudy()) - //{ - // // We get the list of each series from that study index, and open it - // QList seriesList = medDataManager::instance()->getSeriesListFromStudy(index); - // if (seriesList.count() > 0) - // { - // bool userIsOk = true; - // - // if (seriesList.count() > 10) - // { - // userIsOk = userValidationForStudyDrop(); - // } - // - // if (userIsOk) - // { - // for(medDataIndex seriesIndex : seriesList) - // { - // this->addData(medDataManager::instance()->retrieveData(seriesIndex)); - // } - // } - // } - //} } bool medViewContainer::userValidationForStudyDrop() @@ -1088,7 +1045,7 @@ void medViewContainer::open(const QString & path) medSettingsManager::instance()->setValue("path", "medViewContainer", path); } -QString indexToFileSysPath(const QString &&index) +QString indexToFileSysPath_local(const QString &&index) { QString pathRes; @@ -1106,9 +1063,9 @@ QString indexToFileSysPath(const QString &&index) void medViewContainer::open_waitForImportedSignal(medDataIndex index, QUuid uuid) { - if(d->expectedPaths.contains(indexToFileSysPath(index.asString()))) + if(d->expectedPaths.contains(indexToFileSysPath_local(index.asString()))) { - d->expectedPaths.removeAll(indexToFileSysPath(index.asString())); + d->expectedPaths.removeAll(indexToFileSysPath_local(index.asString())); disconnect(medDataManager::instance(),SIGNAL(dataImported(medDataIndex, QUuid)), this,SLOT(open_waitForImportedSignal(medDataIndex, QUuid))); if (index.isValid()) { @@ -1343,9 +1300,9 @@ QString medViewContainer::saveScene() void medViewContainer::addMetadataToQDomElement(medAbstractData *data, QDomElement patientInfo, QString metadata) { - if (data->hasMetaData(metadata) && data->metadata(metadata) != "") + if (data->hasMetaData(metadata) && data->fecthMetaData(metadata) != "") { - patientInfo.setAttribute(metadata, data->metadata(metadata)); + patientInfo.setAttribute(metadata, data->fecthMetaData(metadata)); } } diff --git a/src/layers/medCore/legacy/gui/viewContainers/medViewContainer.h b/src/layers/medCore/legacy/gui/viewContainers/medViewContainer.h index ae03644c18..8fdc4d1388 100644 --- a/src/layers/medCore/legacy/gui/viewContainers/medViewContainer.h +++ b/src/layers/medCore/legacy/gui/viewContainers/medViewContainer.h @@ -164,4 +164,4 @@ private slots: }; -QString indexToFileSysPath(const QString &&index); +QString indexToFileSysPath_local(const QString &&index); diff --git a/src/layers/medCore/legacy/views/medAbstractLayeredView.cpp b/src/layers/medCore/legacy/views/medAbstractLayeredView.cpp index a8a814e58c..bdb364c68b 100644 --- a/src/layers/medCore/legacy/views/medAbstractLayeredView.cpp +++ b/src/layers/medCore/legacy/views/medAbstractLayeredView.cpp @@ -506,7 +506,7 @@ void medAbstractLayeredView::write(QString &path) layerDescription.setAttribute("id", i); // Generating filename - QString currentFile = layerData(i)->metadata("SeriesDescription") + fileExtension; + QString currentFile = layerData(i)->fecthMetaData("SeriesDescription") + fileExtension; // Cleaning filename currentFile = currentFile.replace('/', '_').replace('\\', '_'); diff --git a/src/layers/medCore/legacy/views/navigators/medAbstractImageViewNavigator.cpp b/src/layers/medCore/legacy/views/navigators/medAbstractImageViewNavigator.cpp index 91cf9c51ac..9edebc2c2a 100644 --- a/src/layers/medCore/legacy/views/navigators/medAbstractImageViewNavigator.cpp +++ b/src/layers/medCore/legacy/views/navigators/medAbstractImageViewNavigator.cpp @@ -110,10 +110,10 @@ void medAbstractImageViewNavigator::updateTimeLineParameter() if(data->hasMetaData("SequenceDuration") && data->hasMetaData("SequenceFrameRate")) { - double sd = data->metadata("SequenceDuration").toDouble(); + double sd = data->fecthMetaData("SequenceDuration").toDouble(); sequenceDuration = (sequenceDuration < sd) ? sd : sequenceDuration; - double sf = data->metadata("SequenceFrameRate").toDouble(); + double sf = data->fecthMetaData("SequenceFrameRate").toDouble(); sequenceFrameRate = (sequenceFrameRate < sf) ? sf : sequenceFrameRate; viewHasTemporalData = true; diff --git a/src/layers/medCore/process/arithmetic_operation/medAbstractArithmeticOperationProcess.cpp b/src/layers/medCore/process/arithmetic_operation/medAbstractArithmeticOperationProcess.cpp index b39af7382b..de34a95780 100644 --- a/src/layers/medCore/process/arithmetic_operation/medAbstractArithmeticOperationProcess.cpp +++ b/src/layers/medCore/process/arithmetic_operation/medAbstractArithmeticOperationProcess.cpp @@ -61,11 +61,11 @@ void medAbstractArithmeticOperationProcess::setOutput(medAbstractImageData *data { d->output = data; - QString newSeriesDescription = d->input1->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->input1->fecthMetaData("SeriesDescription"); newSeriesDescription += " " + this->outputNameAddon(); - if (!d->output->hasMetaData(medMetaDataKeys::SeriesDescription.key())) - d->output->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + if (!d->output->hasMetaData(medMetaDataKeys::key("SeriesDescription"))) + d->output->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->input1->metaDataList() ) { diff --git a/src/layers/medCore/process/diffusion_processes/medAbstractDWIMaskingProcess.cpp b/src/layers/medCore/process/diffusion_processes/medAbstractDWIMaskingProcess.cpp index 07e006906c..bcdfc5252e 100644 --- a/src/layers/medCore/process/diffusion_processes/medAbstractDWIMaskingProcess.cpp +++ b/src/layers/medCore/process/diffusion_processes/medAbstractDWIMaskingProcess.cpp @@ -61,11 +61,11 @@ void medAbstractDWIMaskingProcess::setOutput(medAbstractImageData *data) d->output = data; - QString newSeriesDescription = d->input->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->input->fecthMetaData("SeriesDescription"); newSeriesDescription += " " + this->outputNameAddon(); - if (!d->output->hasMetaData(medMetaDataKeys::SeriesDescription.key())) - d->output->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + if (!d->output->hasMetaData(medMetaDataKeys::key("SeriesDescription"))) + d->output->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->input->metaDataList() ) { diff --git a/src/layers/medCore/process/diffusion_processes/medAbstractDiffusionModelEstimationProcess.cpp b/src/layers/medCore/process/diffusion_processes/medAbstractDiffusionModelEstimationProcess.cpp index a8eb638b51..08b7b1494c 100644 --- a/src/layers/medCore/process/diffusion_processes/medAbstractDiffusionModelEstimationProcess.cpp +++ b/src/layers/medCore/process/diffusion_processes/medAbstractDiffusionModelEstimationProcess.cpp @@ -128,11 +128,11 @@ void medAbstractDiffusionModelEstimationProcess::setOutput(medAbstractDiffusionM { d->output = data; - QString newSeriesDescription = d->input->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->input->fecthMetaData("SeriesDescription"); newSeriesDescription += " " + this->outputNameAddon(); - if (!d->output->hasMetaData(medMetaDataKeys::SeriesDescription.key())) - d->output->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + if (!d->output->hasMetaData(medMetaDataKeys::key("SeriesDescription"))) + d->output->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->input->metaDataList() ) { diff --git a/src/layers/medCore/process/diffusion_processes/medAbstractDiffusionScalarMapsProcess.cpp b/src/layers/medCore/process/diffusion_processes/medAbstractDiffusionScalarMapsProcess.cpp index f51ec2d5a7..8ba00fec4b 100644 --- a/src/layers/medCore/process/diffusion_processes/medAbstractDiffusionScalarMapsProcess.cpp +++ b/src/layers/medCore/process/diffusion_processes/medAbstractDiffusionScalarMapsProcess.cpp @@ -54,11 +54,11 @@ void medAbstractDiffusionScalarMapsProcess::setOutput(medAbstractImageData *data { d->output = data; - QString newSeriesDescription = d->input->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->input->fecthMetaData("SeriesDescription"); newSeriesDescription += " " + this->outputNameAddon(); - if (!d->output->hasMetaData(medMetaDataKeys::SeriesDescription.key())) - d->output->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + if (!d->output->hasMetaData(medMetaDataKeys::key("SeriesDescription"))) + d->output->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->input->metaDataList() ) { diff --git a/src/layers/medCore/process/diffusion_processes/medAbstractTractographyProcess.cpp b/src/layers/medCore/process/diffusion_processes/medAbstractTractographyProcess.cpp index 9cc68222ef..c3922e80de 100644 --- a/src/layers/medCore/process/diffusion_processes/medAbstractTractographyProcess.cpp +++ b/src/layers/medCore/process/diffusion_processes/medAbstractTractographyProcess.cpp @@ -54,11 +54,11 @@ void medAbstractTractographyProcess::setOutput(medAbstractFibersData *data) { d->output = data; - QString newSeriesDescription = d->input->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->input->fecthMetaData("SeriesDescription"); newSeriesDescription += " " + this->outputNameAddon(); - if (!d->output->hasMetaData(medMetaDataKeys::SeriesDescription.key())) - d->output->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + if (!d->output->hasMetaData(medMetaDataKeys::key("SeriesDescription"))) + d->output->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->input->metaDataList() ) { diff --git a/src/layers/medCore/process/diffusion_processes/medDiffusionModelEstimationMetaProcess.cpp b/src/layers/medCore/process/diffusion_processes/medDiffusionModelEstimationMetaProcess.cpp index 8fdefcdc1d..926097c78b 100644 --- a/src/layers/medCore/process/diffusion_processes/medDiffusionModelEstimationMetaProcess.cpp +++ b/src/layers/medCore/process/diffusion_processes/medDiffusionModelEstimationMetaProcess.cpp @@ -74,11 +74,11 @@ void medDiffusionModelEstimationMetaProcess::setOutput(medAbstractDiffusionModel { d->output = data; - QString newSeriesDescription = d->input->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->input->fecthMetaData("SeriesDescription"); newSeriesDescription += " " + this->outputNameAddon(); - if (!d->output->hasMetaData(medMetaDataKeys::SeriesDescription.key())) - d->output->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + if (!d->output->hasMetaData(medMetaDataKeys::key("SeriesDescription"))) + d->output->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->input->metaDataList() ) { diff --git a/src/layers/medCore/process/mask_image/medAbstractMaskImageProcess.cpp b/src/layers/medCore/process/mask_image/medAbstractMaskImageProcess.cpp index e5b3b7ad0f..5925d4bd34 100644 --- a/src/layers/medCore/process/mask_image/medAbstractMaskImageProcess.cpp +++ b/src/layers/medCore/process/mask_image/medAbstractMaskImageProcess.cpp @@ -66,11 +66,11 @@ void medAbstractMaskImageProcess::setOutput(medAbstractImageData *data) { d->output = data; - QString newSeriesDescription = d->input->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->input->fecthMetaData("SeriesDescription"); newSeriesDescription += " " + this->outputNameAddon(); - if (!d->output->hasMetaData(medMetaDataKeys::SeriesDescription.key())) - d->output->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + if (!d->output->hasMetaData(medMetaDataKeys::key("SeriesDescription"))) + d->output->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->input->metaDataList() ) { diff --git a/src/layers/medCore/process/morphomath_operation/medAbstractMorphomathOperationProcess.cpp b/src/layers/medCore/process/morphomath_operation/medAbstractMorphomathOperationProcess.cpp index fa83df8bfa..1c84918688 100644 --- a/src/layers/medCore/process/morphomath_operation/medAbstractMorphomathOperationProcess.cpp +++ b/src/layers/medCore/process/morphomath_operation/medAbstractMorphomathOperationProcess.cpp @@ -62,11 +62,11 @@ void medAbstractMorphomathOperationProcess::setOutput(medAbstractImageData *data { d->output = data; - QString newSeriesDescription = d->input->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->input->fecthMetaData("SeriesDescription"); newSeriesDescription += " " + this->outputNameAddon(); - if (!d->output->hasMetaData(medMetaDataKeys::SeriesDescription.key())) - d->output->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + if (!d->output->hasMetaData(medMetaDataKeys::key("SeriesDescription"))) + d->output->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->input->metaDataList() ) { diff --git a/src/layers/medCore/process/single_filter/medAbstractSingleFilterOperationProcess.cpp b/src/layers/medCore/process/single_filter/medAbstractSingleFilterOperationProcess.cpp index fee609478a..7f909233f8 100644 --- a/src/layers/medCore/process/single_filter/medAbstractSingleFilterOperationProcess.cpp +++ b/src/layers/medCore/process/single_filter/medAbstractSingleFilterOperationProcess.cpp @@ -49,11 +49,11 @@ void medAbstractSingleFilterOperationProcess::setOutput(medAbstractImageData *da { d->output = data; - QString newSeriesDescription = d->input->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->input->fecthMetaData("SeriesDescription"); newSeriesDescription += " " + this->outputNameAddon(); - if (!d->output->hasMetaData(medMetaDataKeys::SeriesDescription.key())) - d->output->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + if (!d->output->hasMetaData(medMetaDataKeys::key("SeriesDescription"))) + d->output->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->input->metaDataList() ) { diff --git a/src/layers/medCore/source/medAbstractSource.h b/src/layers/medCore/source/medAbstractSource.h index b22166d3af..3f4ac38cb9 100644 --- a/src/layers/medCore/source/medAbstractSource.h +++ b/src/layers/medCore/source/medAbstractSource.h @@ -60,6 +60,12 @@ class MEDCORE_EXPORT medAbstractSource : public QObject } } + static const entryType stringToEntryType(QString const type) + { + static QMap map = { { "dataset", dataset }, {"folder", folder}, {"both", both} }; + return map[type]; + } + struct datasetAttributes { QMap values; // diff --git a/src/layers/medCore/source/medDataHub.cpp b/src/layers/medCore/source/medDataHub.cpp index 2f6ad96da4..5d394cc905 100644 --- a/src/layers/medCore/source/medDataHub.cpp +++ b/src/layers/medCore/source/medDataHub.cpp @@ -128,7 +128,7 @@ medAbstractData * medDataHub::variantToMedAbstractData(QVariant &data, const med QString name = hruUri.right(hruUri.size() - hruUri.lastIndexOf("\r\n") - 2); QStringList hruUriAsList = hruUri.split("\r\n", QString::SkipEmptyParts); pDataRes->setExpectedName(name); - pDataRes->setMetaData(medMetaDataKeys::SeriesDescription.key(), name); + pDataRes->setMetaData(medMetaDataKeys::key("SeriesDescription"), name); //Todo remove the next asap QString studyDesc; @@ -136,7 +136,7 @@ medAbstractData * medDataHub::variantToMedAbstractData(QVariant &data, const med { studyDesc = hruUriAsList.at(hruUriAsList.size() - 2); } - pDataRes->setMetaData(medMetaDataKeys::StudyDescription.key(), studyDesc); + pDataRes->setMetaData(medMetaDataKeys::key("StudyDescription"), studyDesc); //end todo } else @@ -155,7 +155,7 @@ medAbstractData * medDataHub::variantToMedAbstractData(QVariant &data, const med pDataRes->setDataIndex(index); m_IndexToData[index] = pDataRes; m_IndexToData[index].data(); - getVirtualRepresentation()->addDataFromSource(index, pDataRes); + getVirtualRepresentation()->addData(index, "", pDataRes); connect(pDataRes, &QObject::destroyed, this, &medDataHub::unloadData); } else @@ -289,9 +289,13 @@ medAbstractData * medDataHub::getData(medDataIndex const & index) { bool bOnline, bWritable, bLocal, bCache; QString sourceId = index.sourceId(); - if (sourceId == "fs") + if (sourceId == "fs") { - pDataRes = loadDataFromPathAsIndex(index); + auto dataList = loadDataFromPathAsIndex(index); + if (!dataList.isEmpty()) + { + pDataRes = dataList[0]; + } } else if (m_sourcesHandler->sourceGlobalInfo(sourceId, bOnline, bLocal, bWritable, bCache)) { @@ -314,6 +318,30 @@ medAbstractData * medDataHub::getData(medDataIndex const & index) return pDataRes; } +QList medDataHub::getDataList(medDataIndex const & index) +{ + QList dataResList; + + if (m_IndexToData.contains(index)) + { + dataResList << m_IndexToData[index]; + } + else + { + QString sourceId = index.sourceId(); + if (sourceId == "fs") + { + dataResList << loadDataFromPathAsIndex(index); + } + else + { + //TODO + dataResList << getData(index); + } + } + + return dataResList; +} int medDataHub::waitGetAsyncData(const QString &sourceId, int rqstId) { @@ -414,15 +442,18 @@ void medDataHub::progress(const QString & sourceId, int rqstId, medAbstractSourc } case medAbstractSource::pending: { - m_rqstToNotifMap[rqst]->update(notifLevel::info, 101); - rqst.stampTimeout = QDateTime::currentSecsSinceEpoch() + REQUEST_TIME_OUT; - if (rqst.type == asyncRequestType::getRqstType) - { - pModel->setData(pModel->toIndex(rqst.uri), DATASTATE_ROLE_DATALOADING, DATASTATE_ROLE); - } - else + if (m_rqstToNotifMap.contains(rqst)) { - pModel->setData(pModel->toIndex(rqst.uri), DATASTATE_ROLE_DATAPUSHING, DATASTATE_ROLE); + m_rqstToNotifMap[rqst]->update(notifLevel::info, 101); + rqst.stampTimeout = QDateTime::currentSecsSinceEpoch() + REQUEST_TIME_OUT; + if (rqst.type == asyncRequestType::getRqstType) + { + pModel->setData(pModel->toIndex(rqst.uri), DATASTATE_ROLE_DATALOADING, DATASTATE_ROLE); + } + else + { + pModel->setData(pModel->toIndex(rqst.uri), DATASTATE_ROLE_DATAPUSHING, DATASTATE_ROLE); + } } break; } @@ -488,19 +519,36 @@ void medDataHub::sourceOnlineStatus(const QString & sourceId, bool status) } } -QString fileSysPathToIndex(const QString &path) +QString fileSysPathToIndex(const QString &path, QStringList files) { QString pathTmp = path; pathTmp.replace('\\', '/'); pathTmp.replace('/', "\r\n"); pathTmp = "fs:" + pathTmp; + + if (!files.isEmpty()) + { + if (!pathTmp.endsWith("\r\n")) + { + pathTmp += "\r\n"; + } + for (QString fileName : files) + { + pathTmp += fileName + "|"; + } + if (pathTmp.endsWith("|")) + { + pathTmp = pathTmp.left(pathTmp.size() - 1); + } + } return pathTmp; } -QString indexToFileSysPath(const QString &index) +QStringList indexToFileSysPath(const QString &index) { - QString pathRes; + QStringList pathsRes; + QString basePath; QString uri = index; if (uri.startsWith("fs:")) @@ -508,12 +556,20 @@ QString indexToFileSysPath(const QString &index) int sourceDelimterIndex = uri.indexOf(QString(":")); QStringList uriAsList = uri.right(uri.size() - sourceDelimterIndex - 1).split(QString("\r\n")); - pathRes = uriAsList.join('/'); + QString lastElement = uriAsList.takeLast(); + QStringList files = lastElement.split('|',QString::SkipEmptyParts); + basePath = uriAsList.join('/'); + for (QString fileName : files) + { + pathsRes << basePath + "/" + fileName; + } } - return pathRes; + return pathsRes; } + + class medConvertLocalFileInThread : public QRunnable { public: @@ -526,7 +582,8 @@ class medConvertLocalFileInThread : public QRunnable void run() override { - m_pHub->loadDataFromPath(m_path, m_uuid); + medDataIndex index = fileSysPathToIndex(m_path); + m_pHub->loadDataFromPathAsIndex(index, m_uuid); } medDataHub * m_pHub; @@ -552,7 +609,7 @@ class medCopyLocalFileInThread : public QRunnable if (data) { QString name = (m_index.sourceId()=="fs") ? - med::smartBaseName(indexToFileSysPath(m_index.asString())) : + med::smartBaseName(indexToFileSysPath(m_index.asString())[0]) : m_pHub->getDataName(m_index); @@ -592,6 +649,10 @@ void medDataHub::loadDataFromLocalFileSystem(QString const path, QUuid uuid) QThreadPool::globalInstance()->start(runner); } + + + + void medDataHub::addSource(QString const & pi_sourceId) { m_sourceIdToModelMap[pi_sourceId] = new medSourceModel(this, pi_sourceId); @@ -721,8 +782,9 @@ bool medDataHub::writeResults(QString pi_sourceId, medAbstractData * pi_pData, Q } // //////////////////////////////////////////////////////////////////////////////////////// + // //////////////////////////////////////////////////////////////////////////////////////// - // Check consistency of the proposal with URI + // Check la coherence de la proposition par rapport a l'URI auto limite = std::min(originPath.size(), sugestedPath.size()); for (int i = 0; i < limite; ++i) { @@ -825,7 +887,7 @@ QUuid medDataHub::writeResultsHackV3(medAbstractData &data, bool originSrc) } } - pi_writingPolicyData.baseName = data.metadata(medMetaDataKeys::SeriesDescription.key()); + pi_writingPolicyData.baseName = data.fecthMetaData("SeriesDescription"); writeResults(pi_sourceId, pi_pData, pi_UriOfRelatedData, pi_sugestedPath, pi_writingPolicyData, nullptr); } @@ -1226,91 +1288,167 @@ void medDataHub::releaseRequest() m_mapsRequestMutex.unlock(); } - -medAbstractData * medDataHub::loadDataFromPath(QString const path, QUuid uuid) +int findFirstDifference(const QString& str1, const QString& str2) { - medDataIndex index = fileSysPathToIndex(path); - return loadDataFromPathAsIndex(index, uuid); - // if (m_IndexToData.contains(index)) - // { - // medAbstractData * pDataRes = m_IndexToData[index]; - // emit dataLoaded(fileSysPathToIndex(path)); - // medDataManager::instance()->medDataHubRelay(index, uuid); - // return pDataRes; - // } - - // std::shared_ptr notif = medNotif::createNotif(notifLevel::info , QString("Load File ") + path, " from local file system", -1, -1); - // medAbstractData * pDataRes = medDataImporter::convertSingleDataOnfly(path); - // if (pDataRes) - // { - // QString index = fileSysPathToIndex(path); - - // pDataRes->setDataIndex(index); - - // m_IndexToData[index] = pDataRes; - // m_IndexToData[index].data(); - - // getVirtualRepresentation()->addDataFromFile(path, pDataRes); - // emit dataLoaded(fileSysPathToIndex(path)); - - // medDataManager::instance()->medDataHubRelay(index, uuid); - // notif->update(notifLevel::success, -1, QString("Success")); - - // } - // else - // { - // notif->update(notifLevel::warning, -2, QString("Failure")); - // // medNotif::createNotif(notifLevel::warning, QString("Converting file ") + path, " failed"); - // } - // return pDataRes; + // Iterate through the shorter of the two strings + for (int i = 0; i < std::min(str1.size(), str2.size()); ++i) + { + if (str1[i] != str2[i]) + { + return i; + } + } + + // If no difference is found within the shorter string's length + // the longer string has extra characters at the end + if (str1.size() != str2.size()) + { + return std::min(str1.size(), str2.size()); + } + + // Strings are equal + return std::min(str1.size(), str2.size()); } -medAbstractData * medDataHub::loadDataFromPathAsIndex(medDataIndex index, QUuid uuid) + + +QList medDataHub::loadDataFromPathAsIndex(medDataIndex index, QUuid uuid) { - if (m_IndexToData.contains(index)) + QList dataResList; + + medDataImporter importer; + QMap volumePathsMap; + QMap> volumeRelMap; + QString rootDir; + + std::shared_ptr notif = medNotif::createNotif(notifLevel::info, QString("Load File ") + index.asString(), " from local file system", -1, -1); + + //detectVolume + QStringList paths = indexToFileSysPath(index.asString()); + if (QFileInfo(paths[0]).exists()) { - medAbstractData * pDataRes = m_IndexToData[index]; - emit dataLoaded(index); - medDataManager::instance()->medDataHubRelay(index, uuid); - return pDataRes; + importer.detectVolumes(paths, rootDir, volumePathsMap, volumeRelMap); + //for each volume + for (auto volumeId : volumePathsMap.keys()) + { + //Si volume connue + auto volumeIndex = volumePathsMap[volumeId]; + if (m_IndexToData.contains(volumeIndex)) + { + dataResList << m_IndexToData[volumeIndex]; + emit dataLoaded(volumeIndex); + medDataManager::instance()->medDataHubRelay(volumeIndex, uuid); + return dataResList; + } + else //sinon on itère sur les volumes détectés + { + std::shared_ptr notif = medNotif::createNotif(notifLevel::info, QString("Load File ") + paths[0], " from local file system", -1, -1); + + auto data = importer.convertMultipData(indexToFileSysPath(volumeIndex))[0]; + data->setDataIndex(volumeIndex); + m_IndexToData[volumeIndex] = data; + m_IndexToData[volumeIndex].data(); + + //getVirtualRepresentation()->addData(volumeIndex, volumeRelMap[volumeId].first, data, rootDir); + getVirtualRepresentation()->addData(volumeIndex, volumeRelMap[volumeId].first, data); + //getVirtualRepresentation()->addData(volumeIndex, importer.getVolumeId(data), data); + emit dataLoaded(volumeIndex); + + dataResList << data; + medDataManager::instance()->medDataHubRelay(volumeIndex, uuid); + } + } } - QString path = indexToFileSysPath(index.asString()); - std::shared_ptr notif = medNotif::createNotif(notifLevel::info , QString("Load File ") + QFileInfo(path).fileName(), " from local file system", -1, -1); - medAbstractData * pDataRes = medDataImporter::convertSingleDataOnfly(path); - if (pDataRes) + else { - pDataRes->setDataIndex(index); + medNotif::createNotif(notifLevel::warning, QString("Load unexist file ") + paths[0], " is impossible.", -2); + } - m_IndexToData[index] = pDataRes; - m_IndexToData[index].data(); + return dataResList; +} - getVirtualRepresentation()->addDataFromFile(path, pDataRes); - emit dataLoaded(index); +QString computeRootPathOfListPath(QStringList &fileList, QStringList &relativePathList) +{ + QString rootPath = fileList[0]; - medDataManager::instance()->medDataHubRelay(index, uuid); - notif->update(notifLevel::success, -1, QString("Success")); + int x = 0; + for (int i = 1; i < fileList.size(); i++) + { + x = findFirstDifference(rootPath, fileList[i]); + rootPath = rootPath.left(x); + } + if (rootPath[rootPath.size() - 1] != '/') + { + x = rootPath.lastIndexOf('/') + 1; + rootPath = rootPath.left(x); } - else + + for (auto aFilePath : fileList) { - notif->update(notifLevel::warning, -2, QString("Failure")); + relativePathList << aFilePath.right(aFilePath.size() - x); } - return pDataRes; + + return rootPath; } QList< medDataIndex > medDataHub::getSubData(medDataIndex const & index) { - QList< medDataIndex > listRes; + QList< medDataIndex > listRes; + QString sourceId = index.sourceId(); - medSourceModel * pModel = getModel(index.sourceId()); - if (pModel) + if (sourceId == "fs") { - QModelIndex modelIndexParent = pModel->toIndex(index); - for (int i = 0; i < pModel->rowCount(modelIndexParent); ++i) + QStringList dirPaths; + QStringList paths = indexToFileSysPath(index.asString()); + for (QString path : paths) { - auto sonIndex = pModel->index(i, 0, modelIndexParent); - listRes << pModel->dataIndexFromModelIndex(sonIndex); - } + QFileInfo fi(path); + if (fi.isDir()) + { + dirPaths << path; + } + } + + QMap volumePathsMap; + QMap> volumeRelMap; + QString rootDir; + for (QString dirPath : dirPaths) + { + QFileInfo fi(dirPath); + if (fi.isDir()) + { + medDataImporter importer; + QDir dir(dirPath); + QStringList subPathsFiles = dir.entryList(QDir::Files | QDir::NoDotAndDotDot); + QStringList subPathsDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); + for (int i = 0; i < subPathsFiles.size(); ++i) { subPathsFiles[i] = dirPath + '/' + subPathsFiles[i]; } + for (int i = 0; i < subPathsDirs.size(); ++i) { subPathsDirs[i] = dirPath + '/' + subPathsDirs[i]; } + importer.detectVolumes(subPathsFiles, rootDir, volumePathsMap, volumeRelMap); + //detectVolume(subPathsFiles, volumePathsMap); + for (QString const & index : volumePathsMap) + { + listRes.append(index); + } + for (QString const & subPathsDir : subPathsDirs) + { + listRes.append(fileSysPathToIndex(subPathsDir)); + } + } + } + } + else + { + medSourceModel * pModel = getModel(sourceId); + if (pModel) + { + QModelIndex modelIndexParent = pModel->toIndex(index); + for (int i = 0; i < pModel->rowCount(modelIndexParent); ++i) + { + auto sonIndex = pModel->index(i, 0, modelIndexParent); + listRes << pModel->dataIndexFromModelIndex(sonIndex); + } + } } return listRes; @@ -1324,7 +1462,14 @@ int medDataHub::getDataType(medDataIndex const & index) if (sourceId == "fs") { QModelIndex modelIndex = m_virtualRepresentation->getModelIndex(index); - iRes = m_virtualRepresentation->data(modelIndex, DATATYPE_ROLE).toInt(); + if (modelIndex.isValid()) // is into virtual representation + { + iRes = m_virtualRepresentation->data(modelIndex, DATATYPE_ROLE).toInt(); + } + else // is not into the virtual representation, supposed is directly in file system + { + getDataTypeFS(index, iRes); + } } else { @@ -1332,8 +1477,88 @@ int medDataHub::getDataType(medDataIndex const & index) if (pModel) { QModelIndex modelIndex = pModel->toIndex(index); - iRes = pModel->getDataType(modelIndex); + if (modelIndex.isValid()) + { + iRes = pModel->getDataType(modelIndex); + } + else + { + if (pModel->recursiveFetch(index)) + { + QModelIndex modelIndex = pModel->toIndex(index); + if (modelIndex.isValid()) + { + iRes = pModel->getDataType(modelIndex); + } + } + } } } return iRes; +} + +void medDataHub::getDataTypeFS(const medDataIndex & index, int &iRes) +{ + auto paths = indexToFileSysPath(index.asString()); + + if (paths.size() == 1) + { + QFileInfo fi(paths[0]); + if (fi.exists()) + { + if (fi.isFile()) + { + iRes = DATATYPE_ROLE_DATASET; + } + if (fi.isDir()) + { + QDir dir(paths[0]); + int fileCount = dir.entryList(QDir::Files).size(); + int dirCount = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot).size(); + if (fileCount > 0 && dirCount == 0) iRes = DATATYPE_ROLE_DATASET; + if (fileCount == 0 && dirCount > 0) iRes = DATATYPE_ROLE_FOLDER; + if (fileCount > 0 && dirCount > 0) iRes = DATATYPE_ROLE_BOTH; + } + } + } + else + { + bool isFolder = false; + bool isDataset = false; + int i = 0; + + while (i < paths.size() && (!isFolder || !isDataset)) + { + auto & path = paths[i]; + QFileInfo fi(paths[i]); + if (fi.exists()) + { + isDataset = isDataset || fi.isFile(); + isFolder = isFolder || fi.isDir(); + } + ++i; + } + + if (!isFolder && isDataset) iRes = DATATYPE_ROLE_DATASET; + if ( isFolder && !isDataset) iRes = DATATYPE_ROLE_FOLDER; + if ( isFolder && isDataset) iRes = DATATYPE_ROLE_BOTH; + } +} + +void detectVolume(QStringList paths, QMap & volumePathsMap) +{ + medDataImporter importer; + + auto dataList = importer.convertMultipData(paths); + for (auto & data : dataList) + { + auto volumeId = importer.getVolumeId(data); + auto pathsList = importer.getPaths(data); + + QStringList relFileList; + QString commonPath = computeRootPathOfListPath(pathsList, relFileList); + auto index = fileSysPathToIndex(commonPath, relFileList); + + volumePathsMap[volumeId] = index; + } } \ No newline at end of file diff --git a/src/layers/medCore/source/medDataHub.h b/src/layers/medCore/source/medDataHub.h index 007908404b..706b1ddaba 100644 --- a/src/layers/medCore/source/medDataHub.h +++ b/src/layers/medCore/source/medDataHub.h @@ -39,14 +39,13 @@ class MEDCORE_EXPORT medDataHub : public QObject Q_OBJECT public: - - static medDataHub* instance(QObject *parent = nullptr); ~medDataHub(); QString getDataName(medDataIndex const & index); medAbstractData * getData(medDataIndex const & index); + QList getDataList(medDataIndex const & index); medSourceHandler::datasetAttributes getMetaData(medDataIndex const & index); medSourceHandler::datasetAttributes getOptionalMetaData(medDataIndex const & index); @@ -64,13 +63,15 @@ class MEDCORE_EXPORT medDataHub : public QObject bool pushData(medDataIndex const & index); - medAbstractData * loadDataFromPathAsIndex(medDataIndex index, QUuid uuid = QUuid()); - medAbstractData * loadDataFromPath(QString const path, QUuid uuid = QUuid()); + //medAbstractData * loadDataFromPathAsIndex(medDataIndex index, QUuid uuid = QUuid()); + QList loadDataFromPathAsIndex(medDataIndex index, QUuid uuid = QUuid()); //bool hasData(medDataIndex const & index); QList< medDataIndex > getSubData(medDataIndex const & index); int getDataType(medDataIndex const & index); + void getDataTypeFS(const medDataIndex & index, int &iRes); + // //////////////////////////////////////////////////////////////////////////////////////////// // Members functions for GUI // ------------ Members functions to deal with datamodel Advanced Accessors @@ -143,5 +144,8 @@ public slots: }; -QString fileSysPathToIndex(const QString &path ); -QString indexToFileSysPath(const QString &index); \ No newline at end of file +QString fileSysPathToIndex(const QString &path, QStringList files = {}); +QStringList indexToFileSysPath(const QString &index); + +QString computeRootPathOfListPath(QStringList &fileList, QStringList &relativePathList); +void detectVolume(QStringList paths, QMap & volumePathsMap); \ No newline at end of file diff --git a/src/layers/medCore/source/medDataImporter.cpp b/src/layers/medCore/source/medDataImporter.cpp index ea8f63a30a..1656cded25 100644 --- a/src/layers/medCore/source/medDataImporter.cpp +++ b/src/layers/medCore/source/medDataImporter.cpp @@ -13,6 +13,7 @@ #include +#include #include // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -103,11 +104,69 @@ QList medDataImporter::convertMultipData(QString path) auto volumes = m_pathsVolumesMap.keys(); for (auto &volume : volumes) { - auto readers = getSuitableReader(m_pathsVolumesMap[volume], &m_availablesReadersVolumesMap[volume]); + //auto readers = getSuitableReader(m_pathsVolumesMap[volume], &m_availablesReadersVolumesMap[volume]); + QList readers; + for (auto reader : m_availablesReadersVolumesMap[volume]) + { + readers.push_back(static_cast(medAbstractDataFactory::instance()->reader(reader))); + } auto medData = readFiles(readers, m_pathsVolumesMap[volume], &m_currentReaderVolumesMap[volume]); - m_meddataVolumesMap[volume] = medData; - listRes.push_back(medData); + if (medData) + { + m_meddataVolumesMap[volume] = medData; + listRes.push_back(medData); + } + } + + return listRes; +} + +/** +* @brief Convert a data from files to a medAbstractData, and keep conversion context. +* @param paths of files that contains parts of a same data. +* @return A pointer to the medAbstractData if conversion was successful, nullptr otherwise. +*/ +medAbstractData * medDataImporter::convertSingleData(QStringList paths) +{ + reset(); + + medAbstractData *medDataRes = nullptr; + QString volume; //default volume is empty because here you used only one volume + + QStringList &fileList = paths; + auto readers = getSuitableReader(fileList, &m_availablesReadersVolumesMap[volume]); + medDataRes = readFiles(readers, fileList, &m_currentReaderVolumesMap[volume]); + + m_pathsVolumesMap[volume] = fileList; + m_meddataVolumesMap[volume] = medDataRes; + + return medDataRes; +} + +QList medDataImporter::convertMultipData(QStringList paths) +{ + reset(); + + QList listRes; + + findVolumesInFiles(paths); + auto volumes = m_pathsVolumesMap.keys(); + for (auto &volume : volumes) + { + //auto readers = getSuitableReader(m_pathsVolumesMap[volume], &m_availablesReadersVolumesMap[volume]); + QList readers; + for (auto reader : m_availablesReadersVolumesMap[volume]) + { + readers.push_back(static_cast(medAbstractDataFactory::instance()->reader(reader))); + } + auto medData = readFiles(readers, m_pathsVolumesMap[volume], &m_currentReaderVolumesMap[volume]); + + if (medData) + { + m_meddataVolumesMap[volume] = medData; + listRes.push_back(medData); + } } return listRes; @@ -243,29 +302,66 @@ medAbstractData * medDataImporter::readFiles(QList &rea } /** - * @fn void medDataImporter::findVolumesInDirectory(QString &path) - * @brief Searches volumes/data in directory or a file - * @param [in] path Full pathname of the file. + * @fn medAbstractDataReader* medDataImporter::getReaderForFile(QList &readers, QString file, int &index) + * @brief Searches for a reader able to read the file + * @param [in] readers List of possible readers. + * @param [in] file File to be read. + * @param [in,out] index Position in the list of the reader selected to read the file. */ -void medDataImporter::findVolumesInDirectory(QString &path) +medAbstractDataReader* medDataImporter::getReaderForFile(QList &readers, QString file, int &index) +{ + for (int i=0; icanRead(file) && readers[i]->readInformation(file)) + { + index = i; + return readers[i]; + } + } + + index = -1; + return nullptr; +} + +void medDataImporter::findVolumesInFiles(QStringList &fileList) { + static int count = 0; + count++; + qDebug() << "count = " << count << "\n\n"; QStringList readersID = medAbstractDataFactory::instance()->readers(); - QStringList fileList = listFilesOfData(path); QList readers; for (auto reader : readersID) { readers.push_back(static_cast(medAbstractDataFactory::instance()->reader(reader))); } + qDebug() << readers.size(); + + medAbstractDataReader* mainReader = nullptr; + int readerIndex = -1; + if (!readers.isEmpty()) + { + mainReader = readers[0]; + readerIndex = 0; + } + for (auto file : fileList) { - for (int i=0; icanRead(file) || !mainReader->readInformation(file)) + { + mainReader = getReaderForFile(readers, file, readerIndex); // return an index instead ? + } + + if (mainReader) { - if (readers[i]->canRead(file) && readers[i]->readInformation(file)) + auto volumeId = mainReader->getVolumeId(file); + m_pathsVolumesMap[volumeId] << file; + auto volumeName = mainReader->getVolumeName(file).isEmpty() ? volumeId : mainReader->getVolumeName(file); + m_nameVolumesMap[volumeId] = volumeName; + if (!m_availablesReadersVolumesMap[volumeId].contains(readersID[readerIndex])) // reduce while condition of readFiles function { - QString volume = createVolumeId(dynamic_cast(readers[i]->data())); - m_pathsVolumesMap[volume] << file; - m_availablesReadersVolumesMap[volume] << readersID[i]; + m_availablesReadersVolumesMap[volumeId] << readersID[readerIndex]; } } } @@ -275,6 +371,60 @@ void medDataImporter::findVolumesInDirectory(QString &path) delete reader; } } +//void medDataImporter::findVolumesInFiles(QStringList &fileList) +//{ +// QStringList readersID = medAbstractDataFactory::instance()->readers(); +// QList readers; +// for (auto reader : readersID) +// { +// readers.push_back(static_cast(medAbstractDataFactory::instance()->reader(reader))); +// } +// +// medAbstractDataReader* mainReader = nullptr; +// int readerIndex = -1; +// if(!readers.isEmpty()) +// { +// mainReader = readers[0]; +// readerIndex = 0; +// } +// +// for (auto file : fileList) +// { +// if(!mainReader->canRead(file) || !mainReader->readInformation(file)) +// { +// mainReader = getReaderForFile(readers, file, readerIndex); // return an index instead ? +// } +// +// if(mainReader) +// { +// //QString volume = createVolumeId(dynamic_cast(mainReader->data())); +// auto volumeId = mainReader->getVolumeId(file); +// auto volumeName = mainReader->getVolumeName(file); +// m_pathsVolumesMap[volumeId] << file; +// m_nameVolumesMap[volumeId] << volumeName; +// if(!m_availablesReadersVolumesMap[volumeId].contains(readersID[readerIndex])) // reduce while condition of readFiles function +// { +// m_availablesReadersVolumesMap[volumeId] << readersID[readerIndex]; +// } +// } +// } +// +// for (auto reader : readers) +// { +// delete reader; +// } +//} + +/** + * @fn void medDataImporter::findVolumesInDirectory(QString &path) + * @brief Searches volumes/data in directory or a file + * @param [in] path Full pathname of the file. + */ +void medDataImporter::findVolumesInDirectory(QString &path) +{ + QStringList fileList = listFilesOfData(path); + findVolumesInFiles(fileList); +} /** * @fn medAbstractData * medDataImporter::convertWithOtherReader(medAbstractData *&data, QString readerId) @@ -558,6 +708,164 @@ QStringList medDataImporter::getPaths(medAbstractData * data) return pathsRes; } +/** + * @fn QString medDataImporter::getVolumeId(medAbstractData * data) + * @brief Gets volumeId for a medAbstractData. + * @param [in] data pointer to the data converted by this instance. + * @returns VolumeId. + */ +QString medDataImporter::getVolumeId(medAbstractData * data) +{ + return m_meddataVolumesMap.key(data); +} + + +QString fileSysPathToIndex2(const QString &path, QStringList files) +{ + QString pathTmp = path; + pathTmp.replace('\\', '/'); + pathTmp.replace('/', "\r\n"); + pathTmp = "fs:" + pathTmp; + + if (!files.isEmpty()) + { + if (!pathTmp.endsWith("\r\n")) + { + pathTmp += "\r\n"; + } + for (QString fileName : files) + { + pathTmp += fileName + "|"; + } + if (pathTmp.endsWith("|")) + { + pathTmp = pathTmp.left(pathTmp.size() - 1); + } + } + + return pathTmp; +} + +int findFirstDifference2(const QString& str1, const QString& str2) +{ + // Iterate through the shorter of the two strings + for (int i = 0; i < std::min(str1.size(), str2.size()); ++i) + { + if (str1[i] != str2[i]) + { + return i; + } + } + + // If no difference is found within the shorter string's length + // the longer string has extra characters at the end + if (str1.size() != str2.size()) + { + return std::min(str1.size(), str2.size()); + } + + // Strings are equal + return std::min(str1.size(), str2.size()); +} + +QString computeRootPathOfListPath2(QStringList &fileList, QStringList &relativePathList) +{ + QString rootPath = fileList[0]; + + int x = 0; + if(!fileList.isEmpty()) + { + for (int i = 1; i < fileList.size(); i++) + { + x = findFirstDifference2(rootPath, fileList[i]); + rootPath = rootPath.left(x); + } + + if (rootPath[rootPath.size() - 1] != '/') + { + x = rootPath.lastIndexOf('/') + 1; + rootPath = rootPath.left(x); + } + + for (auto aFilePath : fileList) + { + relativePathList << aFilePath.right(aFilePath.size() - x); + } + } + + return rootPath; +} + +// void medDataImporter::detectVolumes(QStringList pathsIn, QString & rootDir, QMap> & test) +void medDataImporter::detectVolumes(QStringList pathsIn, QString & rootDir, QMap & volumeIndexMap, QMap> & volumeRelativeMap) +{ + findVolumesInFiles(pathsIn); + QStringList volumePaths; + for (auto volumeId : m_pathsVolumesMap.keys()) + { + QStringList relFileList; + QString volumeBasePath = computeRootPathOfListPath2(m_pathsVolumesMap[volumeId], relFileList); + volumePaths << volumeBasePath; + + auto index = fileSysPathToIndex2(volumeBasePath, relFileList); + + volumeIndexMap[volumeId] = index; + volumeRelativeMap[volumeId].first = m_nameVolumesMap[volumeId]; // segfault + qDebug() << "test5"; + } + + QStringList relPathList; + qDebug() << "avant rootDir"; if (!volumePaths.isEmpty()) + { + auto rootList = computeRootPathOfListPath2(volumePaths, relPathList).split('/', QString::SkipEmptyParts); + rootDir = rootList.last(); + } + + for (int i = 0; i < m_pathsVolumesMap.size(); ++i) + { + volumeRelativeMap[m_pathsVolumesMap.keys()[i]].second = relPathList[i]; + } +} +//void medDataImporter::detectVolumes(QStringList paths, QMap & volumePathsMap, QMap & volumeNameMap) +//{ +// findVolumesInFiles(paths); +// QString rootPath; +// QStringList volumePaths; +// QMap relativePathMap; +// +// for (auto volumeId : m_pathsVolumesMap.keys()) +// { +// QStringList relFileList; +// QString volumeBasePath = computeRootPathOfListPath2(m_pathsVolumesMap[volumeId], relFileList); +// volumePaths << volumeBasePath; +// +// auto index = fileSysPathToIndex2(volumeBasePath, relFileList); +// +// volumePathsMap[volumeId] = index; +// } +// +// /* Compréhension : +// toto/tata/test +// toto/tata/1 +// volumeBasePath : toto/tata +// +// */ +// // TODO : faire un lien entre relPathList et les volumeId identifiés +// +// +// +// +// QStringList relPathList; +// rootPath = computeRootPathOfListPath2(volumePaths, relPathList); +// +// int i = 0; +// for (auto volumeId : m_pathsVolumesMap.keys()) +// { +// volumeNameMap[volumeId] = relPathList[i]; +// ++i; +// } +//} + // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -574,7 +882,7 @@ QStringList medDataImporter::getPaths(medAbstractData * data) */ QString medDataImporter::createVolumeId(medAbstractData * data) { - return QString(); //TODO + return data->fecthMetaData("SeriesInstanceuid"); //TODO move the creation of volumeId on the reader } /** diff --git a/src/layers/medCore/source/medDataImporter.h b/src/layers/medCore/source/medDataImporter.h index 9fd124a3cf..a9baab108f 100644 --- a/src/layers/medCore/source/medDataImporter.h +++ b/src/layers/medCore/source/medDataImporter.h @@ -49,9 +49,11 @@ class MEDCORE_EXPORT medDataImporter : public QObject // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Conversion functions from path to medAbstractData // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - static medAbstractData * convertSingleDataOnfly(QString path); - medAbstractData * convertSingleData(QString path); - QList convertMultipData(QString path); + static medAbstractData * convertSingleDataOnfly(QString path); //One path on file or directory represents one data + medAbstractData * convertSingleData(QString path); //One path on file or directory represents one data + QList convertMultipData(QString path); //One path on file or directory represents multiple data + medAbstractData * convertSingleData(QStringList paths); //Many paths on files represent one data + QList convertMultipData(QStringList paths); //Many paths on files represent multiple data // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Control functions @@ -72,7 +74,12 @@ class MEDCORE_EXPORT medDataImporter : public QObject QStringList getAvailableReader(medAbstractData *data = nullptr); QStringList getPaths(QString volumeId = QString()); QStringList getPaths(medAbstractData *data = nullptr); + QString getVolumeId(medAbstractData *data); + medAbstractDataReader* getReaderForFile(QList &readers, QString file, int &index); + + //void detectVolumes(QStringList paths, QMap & volumePathsMap, QMap & volumeNameMap); + void detectVolumes(QStringList pathsIn, QString & rootDir, QMap & volumeIndexMap, QMap> & volumeRelativeMap); private: // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -81,6 +88,7 @@ class MEDCORE_EXPORT medDataImporter : public QObject static QStringList listFilesOfData(QString &path); static QList getSuitableReader(QStringList filename, QStringList *readersId = nullptr); static medAbstractData * readFiles(QList &readers, QStringList &fileList, medAbstractDataReader **usedReader = nullptr); + void findVolumesInFiles(QStringList &fileList); void findVolumesInDirectory(QString &path); // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -99,32 +107,13 @@ class MEDCORE_EXPORT medDataImporter : public QObject private: QMap m_pathsVolumesMap; + QMap m_nameVolumesMap; QMap m_availablesReadersVolumesMap; QMap m_meddataVolumesMap; QMap m_currentReaderVolumesMap; }; -/* -template -inline T medDataImporter::get(QString volumeId, const QMap& map) -{ - T *res = nullptr; - - if (volumeId.isEmpty() && !map.isEmpty()) - { - res = map.first(); - } - else if (map.contains(volumeId)) - { - res = map[volumeId]; - } - - return res; -} - -medAbstractDataReader* medDataImporter::getCurrentReaderInstance(QString volumeId) { return get(volumeId, m_currentReaderVolumesMap); } -QString medDataImporter::getCurrentReader(QString volumeId) { return get(volumeId, m_currentReaderVolumesMap)->identifier(); } -QStringList medDataImporter::getAvailableReader(QString volumeId) { return get(volumeId, m_availablesReadersVolumesMap); } -QStringList medDataImporter::getPaths(QString volumeId) { return get(volumeId, m_pathsVolumesMap); } -*/ +QString fileSysPathToIndex2(const QString &path, QStringList files = {}); +QString computeRootPathOfListPath2(QStringList &fileList, QStringList &relativePathList); + diff --git a/src/layers/medCore/source/operating/medSourceModel.cpp b/src/layers/medCore/source/operating/medSourceModel.cpp index d8ec6e7a51..9a8296b87c 100644 --- a/src/layers/medCore/source/operating/medSourceModel.cpp +++ b/src/layers/medCore/source/operating/medSourceModel.cpp @@ -567,6 +567,21 @@ bool medSourceModel::fetch(QStringList uri) //See populateLevelV2 return bRes; } +bool medSourceModel::recursiveFetch(QStringList uri) +{ + bool bRes = true; + + QStringList uriTmp; + + for (int i = 0; (i < uri.size()) && bRes; ++i) + { + uriTmp.append(uri[i]); + bRes = fetch(uriTmp); + } + + return bRes; +} + bool medSourceModel::fetchData(QModelIndex index) { bool bRes = true; diff --git a/src/layers/medCore/source/operating/medSourceModel.h b/src/layers/medCore/source/operating/medSourceModel.h index e9873d18aa..54ca9130cd 100644 --- a/src/layers/medCore/source/operating/medSourceModel.h +++ b/src/layers/medCore/source/operating/medSourceModel.h @@ -94,6 +94,7 @@ class MEDCORE_EXPORT medSourceModel : public QAbstractItemModel int getColumnInsideLevel(int level, int section) const; int getSectionInsideLevel(int level, int column) const; bool fetch(QStringList uri); + bool recursiveFetch(QStringList uri); bool fetchData(QModelIndex index); QString getSourceIntanceId(); void setOnline(bool pi_bOnline); diff --git a/src/layers/medCore/source/settings/medSourcesLoader.cpp b/src/layers/medCore/source/settings/medSourcesLoader.cpp index b2db353d39..9a15bc6b9a 100644 --- a/src/layers/medCore/source/settings/medSourcesLoader.cpp +++ b/src/layers/medCore/source/settings/medSourcesLoader.cpp @@ -30,6 +30,8 @@ #include +#include + medSourcesLoader *medSourcesLoader::s_instance = nullptr; medSourcesLoader *medSourcesLoader::instance(QObject *parent) @@ -125,8 +127,7 @@ bool medSourcesLoader::removeCnx(QString const & instanceId) saveToDisk(); emit sourceRemoved(&(*oldCnx)); QTimer::singleShot(5*60*1000, this, [oldCnx]() - { - //Do nothing into the lambda because oldCnx is a shared pointer copied by value passing. Then it will be automatically deleted at the end of lambda execution/scope. + { //Do nothing into the lambda because oldCnx is a shared pointer copied by value passing. Then it will be automatically deleted at the end of lambda execution/scope. //Solution to avoid this timer is to used only QSharedPointer when used a source instance. }); //the removed connection will be deleted after 5 min of secured time gap } @@ -259,6 +260,95 @@ QString medSourcesLoader::getPath() return m_CnxParametersFile == MED_DATASOURCES_FILENAME ? m_CnxParametersPath : m_CnxParametersPath + "/" + m_CnxParametersFile; } +QString medSourcesLoader::path() +{ + QString cnxParametersFile = MED_DATASOURCES_FILENAME; + QString cnxParametersPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/" + QCoreApplication::organizationName() + "/" + QCoreApplication::applicationName(); + + auto cnxParametersSaved = medSettingsManager::instance()->value("Sources", "Conf dir", ".").toString(); + + QFileInfo info(cnxParametersSaved); + if (info.isFile()) + { + cnxParametersFile = info.fileName(); + cnxParametersPath = info.dir().path(); + } + else if (QDir(cnxParametersSaved).exists()) + { + cnxParametersPath = cnxParametersSaved; + } + + return cnxParametersPath + '/' + cnxParametersFile; +} + +bool medSourcesLoader::initSourceLoaderCfg(QString src, QString dst) +{ + bool bRes = true; + + QFile file(src); + + if (!file.open(QFile::ReadOnly | QIODevice::Text)) + { + bRes = false; + } + else + { + int iCnxOk = 0; + int iCnxWithoutPlugin = 0; + int iCnxInvalid = 0; + + file.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner); + QString content = file.readAll(); + file.close(); + + + qWarning() << content; + QJsonDocument jsonSaveDoc = QJsonDocument::fromJson(content.toUtf8()); + QJsonArray entries = jsonSaveDoc.array(); + for (QJsonValueRef & entry : entries) + { + auto obj = entry.toObject(); + + if (obj.contains("sourceType") && obj["sourceType"].isString() && !obj["sourceType"].toString().isEmpty() && + obj.contains("cnxId") && obj["cnxId"].isString() && !obj["cnxId"].toString().isEmpty() && + obj.contains("cnxName") && obj["cnxName"].isString() && !obj["cnxName"].toString().isEmpty()) + { + if (obj["sourceType"].toString() == "medSQLite" && obj["cnxId"].toString() == "medSQLite_default") + { + if (obj.contains("parameters") && obj["parameters"].isObject()) + { + QJsonObject params = obj["parameters"].toObject(); + if (params.contains("LocalDataBasePath") && params["LocalDataBasePath"].isObject()) + { + QJsonObject localDataBasePath = params["LocalDataBasePath"].toObject(); + localDataBasePath["value"] = medStorage::dataLocation(); + + params["LocalDataBasePath"] = localDataBasePath; + obj["parameters"] = params; + + entry = obj; + + jsonSaveDoc.setArray(entries); + } + } + } + } + } + + + if (!file.open(QFile::WriteOnly | QIODevice::Text)) + { + bRes = false; + } + else + { + file.write(jsonSaveDoc.toJson()); + } + } + + return bRes; +} + @@ -303,6 +393,7 @@ medSourcesLoader::medSourcesLoader(QObject *parent) m_CnxParametersPath = cnxParametersSaved; } } + bool medSourcesLoader::saveToDisk() const { bool bRes = true; @@ -449,7 +540,7 @@ void medSourcesLoader::reloadCnx(QJsonObject &obj) int iAppliedParametersCount = 0; auto pDataSource = createInstanceOfSource(obj["sourceType"].toString()); - pDataSource->initialization(obj["cnxId"].toString()); + pDataSource->initialization(obj["cnxId"].toString()); //TODO HANDLE return (especily when SQLDriver is not loaded) pDataSource->setInstanceName(obj["cnxName"].toString()); auto normalParameters = pDataSource->getAllParameters(); auto cipherParameters = pDataSource->getCipherParameters(); diff --git a/src/layers/medCore/source/settings/medSourcesLoader.h b/src/layers/medCore/source/settings/medSourcesLoader.h index 078543bf27..96ff0994c1 100644 --- a/src/layers/medCore/source/settings/medSourcesLoader.h +++ b/src/layers/medCore/source/settings/medSourcesLoader.h @@ -28,7 +28,7 @@ class QJsonDocument; class QMutex; template class QSharedPointer; -#ifndef ED_DATASOURCES_FILENAME +#ifndef MED_DATASOURCES_FILENAME #define MED_DATASOURCES_FILENAME "DataSources.json" #endif // !ED_DATASOURCES_FILENAME @@ -70,6 +70,9 @@ class MEDCORE_EXPORT medSourcesLoader : public QObject bool setPath(QString path); QString getPath(); + static QString path(); + static bool initSourceLoaderCfg(QString src, QString dst); + public slots: void changeSourceOrder(int oldPlace, int newPlace); diff --git a/src/layers/medCore/source/threadPool/medConversionTask.cpp b/src/layers/medCore/source/threadPool/medConversionTask.cpp index 0f988f05de..b58b1905bc 100644 --- a/src/layers/medCore/source/threadPool/medConversionTask.cpp +++ b/src/layers/medCore/source/threadPool/medConversionTask.cpp @@ -40,7 +40,7 @@ void medConversionTask::run() m_IndexToData[index] = pDataRes; m_IndexToData[index].data(); - medDataHub::instance(nullptr)->getVirtualRepresentation()->addDataFromFile(m_path, pDataRes); + medDataHub::instance(nullptr)->getVirtualRepresentation()->addData(m_path, "", pDataRes); if(!m_uuid.isNull()) medDataManager::instance()->medDataHubRelay(index, m_uuid); //TODO Remove when compatibility with medDataManager will be deprecated emit medDataHub::instance(nullptr)->dataLoaded(m_path); diff --git a/src/layers/medCore/source/virtualRepresentation/medVirtualRepresentation.cpp b/src/layers/medCore/source/virtualRepresentation/medVirtualRepresentation.cpp index e914200c89..a932301edc 100644 --- a/src/layers/medCore/source/virtualRepresentation/medVirtualRepresentation.cpp +++ b/src/layers/medCore/source/virtualRepresentation/medVirtualRepresentation.cpp @@ -11,77 +11,14 @@ #include #include -#include -#include -#include - #include #include -#define MEDDATA_ROLE 102 //Boolean indicate if a medAbstractData is attached directly or indirectly to an item -#define DATASTATE_ROLE 100 //String defined as below -#define DATASTATE_ROLE_DATANOTLOADED "DataNotLoaded" -#define DATASTATE_ROLE_DATALOADING "DataLoading" -#define DATASTATE_ROLE_DATALOADED "DataLoaded" -#define DATASTATE_ROLE_DATANOTSAVED "DataNotSaved" -#define DATASTATE_ROLE_DATACOMMITTED "DataCommited" -#define DATASTATE_ROLE_DATAPUSHING "DataPushing" -#define DATASTATE_ROLE_DATASAVED "DataSaved" #define DATATYPE_ROLE 103 #define DATATYPE_ROLE_DATASET 0 #define DATATYPE_ROLE_FOLDER 1 #define DATATYPE_ROLE_BOTH 2 -//#define DATAORIGIN_ROLE 200 //String defined as below -//#define DATAORIGIN_ROLE_FILESYSTEM "FS" -//#define DATAORIGIN_ROLE_SOURCE "source" -//#define DATAORIGIN_ROLE_CACHE "cache" -// -//#define DATAURI_ROLE 201 //String URI of the data -//#define DATAGARBAGEABLE_ROLE 202 //Boolean indicates if the data can be automatically removed (if longtime or too much data) -//#define DATAISDIRECTORY_ROLE 203 //Boolean indicates if an item is a pure directory -// -//#define DATANAME_ROLE 300 -// -//#define INVALID_ENTRY "invalidEntry.json" - -struct conversionTask -{ - bool readWrite; - medAbstractData * data; - QString path; - QString name; -}; - - -class conversionWorker : public QRunnable -{ -public: - void run() - { - while (!conversionQueue->empty()) - { - conversionTask conv = conversionQueue->dequeue(); - if (conv.readWrite) - { - medDataImporter::convertSingleDataOnfly(conv.path); - //TODO - } - else - { - QString filePath = conv.path + QDir::separator() + conv.name; - if (medDataExporter::convertSingleDataOnfly(conv.data, filePath)) - { - //TODO - } - } - } - QThread::currentThread()->wait(1000); - } - - QQueue *conversionQueue; -}; - class medVirtualRepresentationPrivate { public: @@ -90,19 +27,17 @@ class medVirtualRepresentationPrivate medStringParameter basePath; medIntParameter dayBeforeRemove; - //QMap > flatTree; //Path, Dirs list, files list - QMap jsonPathsToAbstractData; QMultiMap uriToJsonPaths; QMap uriToAbstractData; - - QQueue conversionQueue; }; - - +/** + * @brief Constructs a new medVirtualRepresentation object. + * @param parent The optional parent object. + */ medVirtualRepresentation::medVirtualRepresentation(QObject *parent): QStandardItemModel(parent), d(new medVirtualRepresentationPrivate(this)) { setColumnCount(1); @@ -111,59 +46,28 @@ medVirtualRepresentation::medVirtualRepresentation(QObject *parent): QStandardIt connect(&d->basePath, &medStringParameter::valueChanged, this, &medVirtualRepresentation::fetch); connect(this, &QStandardItemModel::itemChanged, this, &medVirtualRepresentation::renameByItem); fetch(d->basePath.value()); -} +} +/** + * @brief Destructs the medVirtualRepresentation object. + */ medVirtualRepresentation::~medVirtualRepresentation() { delete d; } +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// +// ////////////// File system handling /////// +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// -bool medVirtualRepresentation::readFileEntry(QString filePath, QString &dataOrigine, QString &dataURI, bool &dataGarbadgeable) -{ - bool bRes = false; - - if (!filePath.isEmpty()) - { - QFile entryFile(filePath); - if (entryFile.open(QFile::ReadOnly)) - { - QString content = entryFile.readAll(); - entryFile.close(); - bRes = readJson(content.toUtf8(), dataOrigine, dataURI, dataGarbadgeable); - } - } - - return bRes; -} - -bool medVirtualRepresentation::writeFileEntry(QJsonObject const & entry, QString filePath, QString fileName) -{ - bool bRes = false; - - if (!filePath.isEmpty() && !fileName.isEmpty()) - { - QFile entryFile(filePath + '/' + fileName + ".json"); - if (entryFile.open(QFile::WriteOnly | QFile::Truncate)) - { - QJsonDocument jsonDoc; - jsonDoc.setObject(entry); - QByteArray data = jsonDoc.toJson(); - bRes = entryFile.write(data) == data.length(); - } - } - - return bRes; -} - - - - - - - - +/** + * @brief Removes an item (in the model and the file system). + * @param index The index of the item to remove. + * @return True if the item was removed successfully, false otherwise. + */ bool medVirtualRepresentation::remove(QModelIndex index) { bool bRes = false; @@ -178,21 +82,32 @@ bool medVirtualRepresentation::remove(QModelIndex index) return bRes; } - +/** + * @brief Renames an item. + * @param index The index in model of the item to rename. + * @param newName The new name of the item. + * @return True if the item was renamed successfully, false otherwise. + */ bool medVirtualRepresentation::rename(QModelIndex index, QString newName) { bool bRes = false; - QDir dir(getPath(index.parent())); + QDir dir(getPath(index.parent())); bRes = dir.rename(data(index, DATANAME_ROLE).toString(), newName); return bRes; } +/** + * @brief Creates a new item (directory type). + * @param parent The parent index of the new item. + * @param dirName The name of the new item. + * @return True if the item was created successfully, false otherwise. + */ bool medVirtualRepresentation::create(QModelIndex parent, QString dirName) { bool bRes = false; - + QStandardItem * pParentItem = nullptr; if (parent.isValid()) { @@ -205,73 +120,53 @@ bool medVirtualRepresentation::create(QModelIndex parent, QString dirName) auto ptrItem = new QStandardItem(dirName); ptrItem->setData(DATATYPE_ROLE_FOLDER, DATATYPE_ROLE); ptrItem->setData(dirName, DATANAME_ROLE); - + pParentItem->appendRow(ptrItem); bRes = createFSDirectory(getPath(parent), dirName); - + emit expandData(parent, true); - + if (dirName == "tmp") { emit editIndex(indexFromItem(ptrItem)); } - - return bRes; -} - - - - -bool medVirtualRepresentation::createFSDirectory(QString path, QString dirName) -{ - bool bRes = false; - - QString dirPath = path + '/' + dirName; - QDir dir(dirPath); - if (!path.isEmpty() && !dirName.isEmpty() && !dir.exists()) - { - bRes = dir.mkpath(dirPath); - } - - return bRes; -} - -bool medVirtualRepresentation::renameFSEntry(QString path) -{ - return false; -} - -bool medVirtualRepresentation::removeFSDir(QString path) //c:/toto/titi/tata/T13D.json -> c:/toto/titi/tata/T13D/ -{ - return QDir(path).removeRecursively(); -} - -bool medVirtualRepresentation::removeFSFile(QString path) -{ - bool bRes = true; - - auto pathAsLst = path.split('/'); - QString fileNameFilter = pathAsLst.last() + ".*"; - pathAsLst.pop_back(); - path = pathAsLst.join('/'); - QDir dir(path, fileNameFilter, QDir::Name | QDir::IgnoreCase, QDir::Files); - for (const QString & filename : dir.entryList()) - { - bRes &= dir.remove(filename); - } return bRes; } -bool medVirtualRepresentation::moveFSEntry(QString oldPath, QString newPath) -{ - return false; -} - - - -//TODO regarder pour les 4 methodes suivantes ce qui a ete fait pour les medSourceModel +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// +// ////////////// Drag and drop section /////// +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// +/** + * @brief Handles dropped MIME data. + * + * This function is called when MIME data is dropped onto the model. + * It determines whether the data can be dropped and, if so, performs the appropriate action (e.g., copying or moving the data). + * + * Qt's documentation says : + * Handles the data supplied by a drag and drop operation that ended with the given action. + * Returns true if the data and action were handled by the model; otherwise returns false. + * The specified row, column and parent indicate the location of an item in the model where the operation ended. + * It is the responsibility of the model to complete the action at the correct location. + * For instance, a drop action on an item in a QTreeView can result in new items either being inserted as children of the item specified by row, column, and parent, or as siblings of the item. + * When row and column are -1 it means that the dropped data should be considered as dropped directly on parent. Usually this will mean appending the data as child items of parent. + * If row and column are greater than or equal zero, it means that the drop occurred just before the specified row and column in the specified parent. + * The mimeTypes() member is called to get the list of acceptable MIME types. + * This default implementation assumes the default implementation of mimeTypes(), which returns a single default MIME type. + * If you reimplement mimeTypes() in your custom model to return multiple MIME types, you must reimplement this function to make use of them. + * + * @param data The MIME data that was dropped. + * @param action The drop action that was requested (e.g., Qt::CopyAction, Qt::MoveAction). + * @param row The row where the data was dropped. + * @param column The column where the data was dropped. + * @param parent The parent index of the item where the data was dropped. + * @return True if the data was dropped successfully, false otherwise. + * + * @details Reimplements: QAbstractItemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent). + */ bool medVirtualRepresentation::dropMimeData(const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent) { bool bRes = false; @@ -286,7 +181,7 @@ bool medVirtualRepresentation::dropMimeData(const QMimeData * data, Qt::DropActi { case Qt::CopyAction: case Qt::LinkAction: - addDataFromSource(index, nullptr, parent); break; + addData(index, "", nullptr, parent); break; case Qt::MoveAction: //TODO move default: @@ -298,13 +193,31 @@ bool medVirtualRepresentation::dropMimeData(const QMimeData * data, Qt::DropActi { for (const QUrl & url : data->urls()) { - addDataFromFile(url.toLocalFile(), nullptr, parent); + addData(fileSysPathToIndex(url.toLocalFile()), "", nullptr, parent); } } return bRes; } +/** + * @brief Creates MIME data for the specified model indexes. + * + * This function is called when the user drags data from the model. + * It creates a MIME data object that contains the data to be dragged. + * + * Qt's documentation says : + * Returns an object that contains serialized items of data corresponding to the list of indexes specified. + * The format used to describe the encoded data is obtained from the mimeTypes() function. + * This default implementation uses the default MIME type returned by the default implementation of mimeTypes(). + * If you reimplement mimeTypes() in your custom model to return more MIME types, reimplement this function to make use of them. + * If the list of indexes is empty, or there are no supported MIME types, nullptr is returned rather than a serialized empty list. + * + * @param indexes The list of model indexes to create MIME data for. + * @return A QMimeData object containing the data to be dragged, or nullptr if no data can be dragged. + * + * @details Reimplements: QAbstractItemModel::mimeData(const QModelIndexList &indexes) const. + */ QMimeData * medVirtualRepresentation::mimeData(const QModelIndexList & indexes) const { QMimeData *mimeData = new QMimeData; @@ -329,7 +242,12 @@ QMimeData * medVirtualRepresentation::mimeData(const QModelIndexList & indexes) } else if (origin == DATAORIGIN_ROLE_FILESYSTEM) { - urls.append(QUrl::fromLocalFile(dataUri)); + //urls.append(QUrl::fromLocalFile(dataUri)); + if (!encodedData.isEmpty()) + { + encodedData.append('\0'); + } + encodedData.append(dataUri); } else if (origin == DATAORIGIN_ROLE_CACHE) { @@ -343,6 +261,21 @@ QMimeData * medVirtualRepresentation::mimeData(const QModelIndexList & indexes) return mimeData; } +/** + * @brief Returns a list of MIME types that the model can provide for dragging. + * + * This function is used to determine what types of data the model can drag. + * Here supported types are med/index2 and text/uri-list + * + * Qt's documentation says : + * Returns the list of allowed MIME types. By default, the built-in models and views use an internal MIME type: application/x-qabstractitemmodeldatalist. + * When implementing drag and drop support in a custom model, if you will return data in formats other than the default internal MIME type, reimplement this function to return your list of MIME types. + * If you reimplement this function in your custom model, you must also reimplement the member functions that call it: mimeData() and dropMimeData(). + * + * @return A list of MIME types that the model can provide for dragging. + * + * @details Reimplements: QAbstractItemModel::mimeTypes() const. + */ QStringList medVirtualRepresentation::mimeTypes() const { QStringList types; @@ -350,113 +283,459 @@ QStringList medVirtualRepresentation::mimeTypes() const return types; } +/** + * @brief Returns the drop actions that are supported by the model. + * + * This function determines what types of drop actions (e.g., copying, moving) are supported by the model. + * + * Qt's documentation says : + * Returns the drop actions supported by this model. + * The default implementation returns Qt::CopyAction. + * Reimplement this function if you wish to support additional actions. + * You must also reimplement the dropMimeData() function to handle the additional operations. + * + * @return A set of Qt::DropAction flags indicating the supported drop actions. + * + * @details Reimplements: QAbstractItemModel::supportedDropActions() const. + */ Qt::DropActions medVirtualRepresentation::supportedDropActions() const { return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; } + +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// +// ////////////// Other functions section /////// +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// + +/** + * @brief Converts a medDataIndex to a QModelIndex. + * + * This function translates an index from the medInria data store to a corresponding index in the model. + * This allows you to interact with data in the model using the medInria indexing scheme. + * + * @param index The medDataIndex to convert. + * @return The corresponding QModelIndex in the model, or an invalid index if the conversion fails. + */ +QModelIndex medVirtualRepresentation::getModelIndex(medDataIndex index) +{ + QModelIndex indexRes; + QString indexAsString = index.asString(); + if (d->uriToJsonPaths.contains(indexAsString)) + { + QString jsonPath = d->uriToJsonPaths.value(indexAsString); + indexRes = getIndex(jsonPath); + } + + return indexRes; +} + +/** + * @brief Retrieves the list of medVirtualRepresentation's parameters . + * + * This function retrieves the list of all the medAbstractParameter objects of medVirtualRepresentation. + * These parameters may be used to configure or control the behavior of medVirtualRepresentation. + * + * @return A list of medAbstractParameter objects. + */ QList medVirtualRepresentation::getParams() { return {& d->basePath, & d->dayBeforeRemove}; } +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// +// ////////////// Public slots section /////// +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// - - -bool medVirtualRepresentation::fetch(QString const & pi_path) +/** + * @brief Adds generated data to the model. + * @param data The data to add. + * @param name The optional name of the data. + */ +void medVirtualRepresentation::addGeneratedData(medAbstractData * data, QString name) { - bool bRes = true; - - - QString basePath = d->basePath.value(); - - QDirIterator it(pi_path, QStringList() << "*.json", QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); - while (it.hasNext()) + if (data) { - QString aPath = it.next(); - QString aRelativePath = aPath.right(aPath.length()-(basePath.length()+1)); - auto aPathSplited = aRelativePath.split('/'); + //Est-ce qu'il existe deja ? + QString dataName; - if (!QDir(aPath).exists()) + if (!name.isEmpty()) { - QString dataOrigine; - QString dataURI; - bool dataGarbageable = false; + dataName = name; + } + else if (!data->getExpectedName().isEmpty()) + { + dataName = data->getExpectedName(); + } + else + { + dataName = "tmp data"; + } - bool bValidEntryFile = readFileEntry(aPath, dataOrigine, dataURI, dataGarbageable); + QStandardItem *item = invisibleRootItem(); - if (bValidEntryFile) - { - QFileInfo fileInfo(aPath); - QDateTime fileCreationTime = fileInfo.birthTime(); - QDateTime currentDate = QDateTime::currentDateTime(); - if (currentDate > fileCreationTime.addDays(d->dayBeforeRemove.value()) && dataGarbageable) - { - removeFSFile(aPath); - } - else - { - QModelIndex lastFolderIndex; + QString tmpName = dataName; + QString dataPath = getPath(); + int indexPlace = 0; - for (int i = 0; i < aPathSplited.size() - 1; ++i) - { - lastFolderIndex = createFolderIndex(aPathSplited.mid(0, i + 1)); - } - - QStandardItem * parentItem = lastFolderIndex.isValid() ? itemFromIndex(lastFolderIndex) : invisibleRootItem(); - QStandardItem * child = nullptr; - - QString qualifiedDataName = aPathSplited.last(); - QString dataName = qualifiedDataName.left((qualifiedDataName.length() - 5)); - + computeNameAndPlace(item, "", dataName, indexPlace, tmpName); - for (int i = 0; i < parentItem->rowCount() && child == nullptr; ++i) - { - QStandardItem * aChild = parentItem->child(i); - if (aChild->data(Qt::DisplayRole).toString() == dataName) - { - child = aChild; - } - } - if (child == nullptr) - { - QStandardItem * newItem = new QStandardItem(); - newItem->setData(dataName, Qt::DisplayRole); - newItem->setData(dataName, DATANAME_ROLE); - newItem->setData(dataOrigine, DATAORIGIN_ROLE); - newItem->setData(dataURI, DATAURI_ROLE); - newItem->setData(dataGarbageable, DATAGARBAGEABLE_ROLE); - newItem->setData(DATATYPE_ROLE_DATASET, DATATYPE_ROLE); - parentItem->insertRow(parentItem->rowCount(), newItem); - } - else - { - child->setData(dataOrigine, DATAORIGIN_ROLE); - child->setData(dataURI, DATAURI_ROLE); - child->setData(dataGarbageable, DATAGARBAGEABLE_ROLE); - child->setData(DATATYPE_ROLE_BOTH, DATATYPE_ROLE); - } + QStandardItem *newItem = new QStandardItem(tmpName); + newItem->setData(tmpName, DATANAME_ROLE); + newItem->setData(DATAORIGIN_ROLE_CACHE, DATAORIGIN_ROLE); + newItem->setData(tmpName, DATAURI_ROLE); + newItem->setData(false, DATAGARBAGEABLE_ROLE); + newItem->setData(DATATYPE_ROLE_DATASET, DATATYPE_ROLE); - } - } - } - else + item->insertRow(indexPlace, newItem); + + auto index = newItem->index(); + QJsonObject jsonObj; + if (writeJson(index, jsonObj)) { - createFolderIndex(aPathSplited); + writeFileEntry(jsonObj, dataPath, dataName); } - } - return bRes; + QString uri = dataName; + insertData(data, uri, dataPath, tmpName); + } } - -bool medVirtualRepresentation::writeJson(const QModelIndex & index, QJsonObject &json) +/** + * @brief Adds data. + * @param medIndex The index of the data in medInria. + * @param volumeName The optional volume name of the data. + * @param data The optional data object to add. + * @param parent The optional parent index of the new item. + */ +void medVirtualRepresentation::addData(medDataIndex medDataIndex, QString volumeName, medAbstractData * data, const QModelIndex & parent) { - bool bRes = index.isValid(); - - if (bRes) + QStandardItem *item = nullptr; + + if (parent.isValid() && parent.model() == this) + { + item = itemFromIndex(parent); + } + else + { + item = invisibleRootItem(); + } + + QString dataName; + QString datOriginRole; + if (medDataIndex.sourceId() == "fs") + { + datOriginRole = DATAORIGIN_ROLE_FILESYSTEM; + if (!volumeName.isEmpty()) + { + dataName = volumeName; + } + else + { + QStringList paths = indexToFileSysPath(medDataIndex.asString()); + if (paths.size() == 1) + { + dataName = QFileInfo(paths[0]).fileName(); + } + else if (paths.size() > 1) + { + QStringList pathAsList = paths[0].split('/', QString::SkipEmptyParts); + dataName = pathAsList[pathAsList.size() - 2]; //the name is the name of last folder + } + } + + } + else + { + datOriginRole = DATAORIGIN_ROLE_SOURCE; + dataName = medDataHub::instance()->getDataName(medDataIndex); + } + + + QString tmpName = dataName; + QString dataPath = getPath(parent); + int indexPlace = 0; + + computeNameAndPlace(item, medDataIndex.asString(), dataName, indexPlace, tmpName); + + QString uri = medDataIndex.asString(); + if (!d->uriToJsonPaths.contains(uri)) + { + + QStandardItem *newItem = new QStandardItem(tmpName); + newItem->setData(tmpName, DATANAME_ROLE); + newItem->setData(datOriginRole, DATAORIGIN_ROLE); + newItem->setData(medDataIndex.asString(), DATAURI_ROLE); + newItem->setData(false, DATAGARBAGEABLE_ROLE); + newItem->setData(DATATYPE_ROLE_DATASET, DATATYPE_ROLE); + + item->insertRow(indexPlace, newItem); + + + auto modelIndex = newItem->index(); + QJsonObject jsonObj; + if (writeJson(modelIndex, jsonObj)) + { + writeFileEntry(jsonObj, dataPath, dataName); + } + + insertData(data, uri, dataPath, tmpName); + } +} + +/** + * @brief Pins the data represented by the given model index. + * + * This function marks the data at the specified model index as pinned. Pinned data is typically not automatically removed from the virtual representation, + * even if it is old or there is a lot of data. + * + * @param modelIndex The index of the data to pin. + */ +void medVirtualRepresentation::pinData(QModelIndex modelIndex) +{ + auto *ptrItem = itemFromIndex(modelIndex); + if (ptrItem) + { + ptrItem->setData(false, DATAGARBAGEABLE_ROLE); + //TODO save new state to filesystem + } +} + +/** + * @brief Unpins the data represented by the given model index. + * + * This function reverses the effect of `pinData()`. Unpinned data may be automatically removed from the virtual representation under certain conditions. + * + * @param modelIndex The index of the data to unpin. + */ +void medVirtualRepresentation::unPinData(QModelIndex modelIndex) +{ + auto *ptrItem = itemFromIndex(modelIndex); + if (ptrItem) + { + ptrItem->setData(true, DATAGARBAGEABLE_ROLE); + //TODO save new state to filesystem + } +} + +/** + * @brief Removes the data represented by the given model index. + * + * This function removes the data and its associated item from the virtual representation. + * + * @param modelIndex The index of the data to remove. + */ +void medVirtualRepresentation::removeData(QModelIndex modelIndex) +{ + //TODO +} + +/** + * @brief Reacts to a data being saved in medInria. + * + * This function is called when data represented by a medDataIndex is saved in medInria. + * It removes any cached data associated with the index and replaces it with a URI pointing to the data in the source location. + * + * @param index The medDataIndex of the saved data. + */ +void medVirtualRepresentation::dataSaved(medDataIndex index) +{ + //TODO OK +} + +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + + +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// +// ////////////// JSon handling section /////// +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// + +/** + * @brief Fetches data from a JSON file. + * + * This function loads Virtual Representation content from a JSON files located at the specified path. + * The path can be an empty string, in which case the default behavior is likely to apply. + * + * @param path The path to the JSON files. (default = "") + * @return True if the data was fetched successfully, false otherwise. + */ +bool medVirtualRepresentation::fetch(QString const & pi_path) +{ + bool bRes = true; + + + QString basePath = d->basePath.value(); + + QDirIterator it(pi_path, QStringList() << "*.json", QDir::Files | QDir::AllDirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories); + while (it.hasNext()) + { + QString aPath = it.next(); + QString aRelativePath = aPath.right(aPath.length() - (basePath.length() + 1)); + auto aPathSplited = aRelativePath.split('/'); + + if (!QDir(aPath).exists()) + { + QString dataOrigine; + QString dataURI; + bool dataGarbageable = false; + + bool bValidEntryFile = readFileEntry(aPath, dataOrigine, dataURI, dataGarbageable); + + if (bValidEntryFile) + { + QFileInfo fileInfo(aPath); + QDateTime fileCreationTime = fileInfo.birthTime(); + QDateTime currentDate = QDateTime::currentDateTime(); + if (currentDate > fileCreationTime.addDays(d->dayBeforeRemove.value()) && dataGarbageable) + { + removeFSFile(aPath); + } + else + { + QModelIndex lastFolderIndex; + + for (int i = 0; i < aPathSplited.size() - 1; ++i) + { + lastFolderIndex = createFolderIndex(aPathSplited.mid(0, i + 1)); + } + + QStandardItem * parentItem = lastFolderIndex.isValid() ? itemFromIndex(lastFolderIndex) : invisibleRootItem(); + QStandardItem * child = nullptr; + + QString qualifiedDataName = aPathSplited.last(); + QString dataName = qualifiedDataName.left((qualifiedDataName.length() - 5)); + + + for (int i = 0; i < parentItem->rowCount() && child == nullptr; ++i) + { + QStandardItem * aChild = parentItem->child(i); + if (aChild->data(Qt::DisplayRole).toString() == dataName) + { + child = aChild; + } + } + + if (child == nullptr) + { + QStandardItem * newItem = new QStandardItem(); + newItem->setData(dataName, Qt::DisplayRole); + newItem->setData(dataName, DATANAME_ROLE); + newItem->setData(dataOrigine, DATAORIGIN_ROLE); + newItem->setData(dataURI, DATAURI_ROLE); + newItem->setData(dataGarbageable, DATAGARBAGEABLE_ROLE); + newItem->setData(DATATYPE_ROLE_DATASET, DATATYPE_ROLE); + parentItem->insertRow(parentItem->rowCount(), newItem); + } + else + { + child->setData(dataOrigine, DATAORIGIN_ROLE); + child->setData(dataURI, DATAURI_ROLE); + child->setData(dataGarbageable, DATAGARBAGEABLE_ROLE); + child->setData(DATATYPE_ROLE_BOTH, DATATYPE_ROLE); + } + + d->uriToJsonPaths.insert(dataURI, aPath); + + } + } + } + else + { + createFolderIndex(aPathSplited); + } + } + + return bRes; +} + +/** + * @brief Reads information from a JSON file entry. + * + * This function reads information about a data entry from a JSON file. + * It extracts the data origin, data URI, and garbage collection flag from the entry. + * + * @param filePath The path to the JSON file. + * @param dataOrigine [OUT] A string to store the data origin retrieved from the file. + * @param dataURI [OUT] A string to store the data URI retrieved from the file. + * @param dataGarbadgeable [OUT] A boolean flag indicating whether the data can be automatically removed (garbage collectable). + * @return True if the information was read successfully, false otherwise. + */ +bool medVirtualRepresentation::readFileEntry(QString filePath, QString &dataOrigine, QString &dataURI, bool &dataGarbadgeable) +{ + bool bRes = false; + + if (!filePath.isEmpty()) + { + QFile entryFile(filePath); + if (entryFile.open(QFile::ReadOnly)) + { + QString content = entryFile.readAll(); + entryFile.close(); + bRes = readJson(content.toUtf8(), dataOrigine, dataURI, dataGarbadgeable); + } + } + + return bRes; +} + +/** + * @brief Writes information to a JSON file entry. + * + * This function writes information about a data entry to a JSON file. + * It stores the provided data origin, data URI, and garbage collection flag in the entry. + * + * @param entry The QJsonObject containing the data to write. + * @param filePath The path to the JSON file. + * @param fileName The name of the file to write to. + * @return True if the information was written successfully, false otherwise. + */ +bool medVirtualRepresentation::writeFileEntry(QJsonObject const & entry, QString filePath, QString fileName) +{ + bool bRes = false; + + if (!filePath.isEmpty() && !fileName.isEmpty()) + { + QFile entryFile(filePath + '/' + fileName + ".json"); + if (entryFile.open(QFile::WriteOnly | QFile::Truncate)) + { + QJsonDocument jsonDoc; + jsonDoc.setObject(entry); + QByteArray data = jsonDoc.toJson(); + bRes = entryFile.write(data) == data.length(); + } + } + + return bRes; +} + +/** + * @brief Writes data from a model index to a JSON object. + * + * This function extracts data from the model at the specified index and stores it in a JSON object. + * The format of the data in the JSON object is likely to be specific to the application. + * + * This function is used to prepare a JSON to call medVirtualRepresentation::writeFileEntry. + * + * @param index The model index of the data to write. + * @param json [OUT] A reference to the QJsonObject to store the data in. + * @return True if the data was written to the JSON object successfully, false otherwise. + */ +bool medVirtualRepresentation::writeJson(const QModelIndex & index, QJsonObject &json) +{ + bool bRes = index.isValid(); + + if (bRes) { auto dataOrigine = data(index, DATAORIGIN_ROLE).toString(); auto dataURI = data(index, DATAURI_ROLE).toString(); @@ -464,12 +743,9 @@ bool medVirtualRepresentation::writeJson(const QModelIndex & index, QJsonObject if (dataOrigine == DATAORIGIN_ROLE_FILESYSTEM) { - if (QFile::exists(dataURI)) - { - json.insert("uriType", QJsonValue::fromVariant(DATAORIGIN_ROLE_FILESYSTEM)); - json.insert("uri", QJsonValue::fromVariant(dataURI)); - json.insert("garbageable", QJsonValue::fromVariant(dataGarbadgeable)); - } + json.insert("uriType", QJsonValue::fromVariant(DATAORIGIN_ROLE_FILESYSTEM)); + json.insert("uri", QJsonValue::fromVariant(dataURI)); + json.insert("garbageable", QJsonValue::fromVariant(dataGarbadgeable)); } else if (dataOrigine == DATAORIGIN_ROLE_SOURCE) { @@ -495,6 +771,20 @@ bool medVirtualRepresentation::writeJson(const QModelIndex & index, QJsonObject return bRes; } +/** + * @brief Reads data from a JSON byte array. + * + * This function parses a JSON byte array and extracts information about a data entry. + * It retrieves the data origin, data URI, and garbage collection flag from the JSON data. + * + * This function is used by medVirtualRepresentation::readFileEntry. + * + * @param array The QByteArray containing the JSON data. + * @param dataOrigine [OUT] A string to store the data origin retrieved from the JSON data. + * @param dataURI [OUT] A string to store the data URI retrieved from the JSON data. + * @param dataGarbadgeable [OUT] A boolean flag indicating whether the data can be automatically removed (garbage collectable). + * @return True if the information was read successfully, false otherwise. + */ bool medVirtualRepresentation::readJson(const QByteArray & array, QString &dataOrigine, QString &dataURI, bool &dataGarbadgeable) { bool bRes = false; @@ -548,260 +838,180 @@ bool medVirtualRepresentation::readJson(const QByteArray & array, QString &dataO return bRes; } - -void medVirtualRepresentation::dataSaved(medDataIndex index) -{ - //TODO OK -} - -void medVirtualRepresentation::addGeneratedData(medAbstractData * data, QString name) -{ - if (data) - { - //Est-ce qu'il existe deja ? - QString dataName; - - if (!name.isEmpty()) - { - dataName = name; - } - else if (!data->getExpectedName().isEmpty()) - { - dataName = data->getExpectedName(); - } - else - { - dataName = "tmp data"; - } - - QStandardItem *item = invisibleRootItem(); - - QString tmpName = dataName; - QString dataPath = getPath(); - int indexPlace = 0; - - computeNameAndPlace(item, "", dataName, indexPlace, tmpName); - - - QStandardItem *newItem = new QStandardItem(tmpName); - newItem->setData(tmpName, DATANAME_ROLE); - newItem->setData(DATAORIGIN_ROLE_CACHE, DATAORIGIN_ROLE); - newItem->setData(tmpName, DATAURI_ROLE); - newItem->setData(false, DATAGARBAGEABLE_ROLE); - newItem->setData(DATATYPE_ROLE_DATASET, DATATYPE_ROLE); - - item->insertRow(indexPlace, newItem); - - auto index = newItem->index(); - QJsonObject jsonObj; - if (writeJson(index, jsonObj)) - { - writeFileEntry(jsonObj, dataPath, dataName); - } - - QString uri = dataName; - if (data) - { - if (!d->uriToAbstractData.contains(uri)) - { - d->uriToAbstractData[uri] = data; - } - } - d->uriToJsonPaths.insert(uri, dataPath + '/' + tmpName); - } -} - -void medVirtualRepresentation::addDataFromSource(medDataIndex dataIndex, medAbstractData * data, const QModelIndex & parent) +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// +// ////////////// File system handling /////// +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// + +/** + * @brief Creates a directory in the file system. + * + * This function creates a new directory at the specified path. + * The directory will be used to store JSON files associated with the model data. + * + * @param path The path to the parent directory where the new directory will be created. + * @param dirName The name of the new directory to create. + * @return True if the directory was created successfully, false otherwise. + */ +bool medVirtualRepresentation::createFSDirectory(QString path, QString dirName) { + bool bRes = false; - //Est-ce qu'il existe deja ? - - QStandardItem *item = nullptr; - - if (parent.isValid() && parent.model() == this) - { - item = itemFromIndex(parent); - } - else - { - item = invisibleRootItem(); - } - - QString dataName = medDataHub::instance()->getDataName(dataIndex); - QString tmpName = dataName; - QString dataPath = getPath(parent); - int indexPlace = 0; - - computeNameAndPlace(item, dataIndex.asString(), dataName, indexPlace, tmpName); - - - QStandardItem *newItem = new QStandardItem(tmpName); - newItem->setData(tmpName, DATANAME_ROLE); - newItem->setData(DATAORIGIN_ROLE_SOURCE, DATAORIGIN_ROLE); - newItem->setData(dataIndex.asString(), DATAURI_ROLE); - newItem->setData(false, DATAGARBAGEABLE_ROLE); - newItem->setData(DATATYPE_ROLE_DATASET, DATATYPE_ROLE); - - item->insertRow(indexPlace, newItem); - - - auto modelIndex = newItem->index(); - QJsonObject jsonObj; - if (writeJson(modelIndex, jsonObj)) + QString dirPath = path + '/' + dirName; + QDir dir(dirPath); + if (!path.isEmpty() && !dirName.isEmpty() && !dir.exists()) { - writeFileEntry(jsonObj, dataPath, dataName); + bRes = dir.mkpath(dirPath); } - - QString uri = dataIndex.asString(); - - d->uriToJsonPaths.insert(uri, dataPath + '/' + tmpName); + return bRes; } -void medVirtualRepresentation::addDataFromFile(QString path, medAbstractData * data, const QModelIndex & parent) +/** + * @brief Renames a file system entry (file or directory). + * + * This function renames a file or directory at the specified path. + * It is likely used to rename JSON files associated with the model data. + * + * @param path The path to the file or directory to rename. + * @return True if the entry was renamed successfully, false otherwise. + */ +bool medVirtualRepresentation::renameFSEntry(QString path) { + //TODO - //Est-ce qu'il existe deja ? - - QStandardItem *item = nullptr; - - if (parent.isValid() && parent.model() == this) - { - item = itemFromIndex(parent); - } - else - { - item = invisibleRootItem(); - } - - QString dataName = QFileInfo(path).fileName(); - QString tmpName = dataName; - QString dataPath = getPath(parent); - int indexPlace = 0; - - computeNameAndPlace(item, path, dataName, indexPlace, tmpName); - - - QStandardItem *newItem = new QStandardItem(tmpName); - newItem->setData(tmpName, DATANAME_ROLE); - newItem->setData(DATAORIGIN_ROLE_FILESYSTEM, DATAORIGIN_ROLE); - newItem->setData(path, DATAURI_ROLE); - newItem->setData(false, DATAGARBAGEABLE_ROLE); - newItem->setData(DATATYPE_ROLE_DATASET, DATATYPE_ROLE); - - item->insertRow(indexPlace, newItem); - - auto index = newItem->index(); - QJsonObject jsonObj; - if (writeJson(index, jsonObj)) + QFileInfo fi(path); + if (fi.exists()) { - writeFileEntry(jsonObj, dataPath, dataName); - } + if (fi.isDir()) + { - QString uri = path; - if (data) - { - if (!d->uriToAbstractData.contains(uri)) + } + else if (fi.isFile()) { - d->uriToAbstractData[uri] = data; + fi.baseName(); + fi.completeSuffix(); } } - d->uriToJsonPaths.insert(uri, dataPath + '/' + tmpName); + return false; } -void medVirtualRepresentation::pinData(QModelIndex modelIndex) +/** + * @brief Removes a directory from the file system. + * + * This function deletes a directory at the specified path. + * The directory is likely used to store JSON files associated with the model data. + * + * @param path The path to the directory to remove. + * @return True if the directory was removed successfully, false otherwise. + */ +bool medVirtualRepresentation::removeFSDir(QString path) //c:/toto/titi/tata/T13D.json -> c:/toto/titi/tata/T13D/ { - auto *ptrItem = itemFromIndex(modelIndex); - if (ptrItem) - { - ptrItem->setData(false, DATAGARBAGEABLE_ROLE); - //TODO save new state to filesystem - } + return QDir(path).removeRecursively(); } -void medVirtualRepresentation::unPinData(QModelIndex modelIndex) +/** + * @brief Removes a file from the file system. + * + * This function deletes a file at the specified path. + * The file is likely a JSON file associated with the model data. + * + * @param path The path to the file to remove. + * @return True if the file was removed successfully, false otherwise. + */ +bool medVirtualRepresentation::removeFSFile(QString path) { - auto *ptrItem = itemFromIndex(modelIndex); - if (ptrItem) + bool bRes = true; + + auto pathAsLst = path.split('/'); + QString fileNameFilter = pathAsLst.last() + ".*"; + pathAsLst.pop_back(); + path = pathAsLst.join('/'); + QDir dir(path, fileNameFilter, QDir::Name | QDir::IgnoreCase, QDir::Files); + for (const QString & filename : dir.entryList()) { - ptrItem->setData(true, DATAGARBAGEABLE_ROLE); - //TODO save new state to filesystem + bRes &= dir.remove(filename); } + + return bRes; } -void medVirtualRepresentation::removeData(QModelIndex modelIndex) +/** + * @brief Moves a file system entry (file or directory). + * + * This function moves a file or directory from one location to another. + * It is likely used to move JSON files associated with the model data. + * + * @param oldPath The path to the source file or directory. + * @param newPath The path to the destination location. + * @return True if the entry was moved successfully, false otherwise. + */ +bool medVirtualRepresentation::moveFSEntry(QString oldPath, QString newPath) { //TODO + return false; } -void medVirtualRepresentation::renameByItem(QStandardItem * item) -{ - QModelIndex index = indexFromItem(item); - QString name = item->data(Qt::DisplayRole).toString(); - - rename(index, name); -} +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// +// ////////////// Cache section /////// +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// + +/** + * @brief Writes data to the cache. + * + * This function stores the provided medAbstractData object in the cache. + * The data is likely written to a file at the specified path with the given name. + * + * @param data The medAbstractData object to store in the cache. + * @param path The path to the cache directory where the data will be stored. + * @param name The name of the file to use for storing the cached data. + * @return True if the data was written to the cache successfully, false otherwise. + */ bool medVirtualRepresentation::writeCacheData(medAbstractData * data, QString path, QString name) { + //TODO return false; } +/** + * @brief Reads data from the cache. + * + * This function attempts to read cached data from a file at the specified path with the given name. + * If successful, it creates a new medAbstractData object and populates it with the cached data. + * + * @param data [OUT] A reference to a medAbstractData pointer that will be set to the newly created object containing the cached data, or nullptr if the data could not be read. + * @param path The path to the cache directory where the data is expected to be stored. + * @param name The name of the file containing the cached data. + * @return True if the data was read from the cache successfully, false otherwise. + */ bool medVirtualRepresentation::readCacheData(medAbstractData *& data, QString path, QString name) -{ - return false; -} - -QModelIndex medVirtualRepresentation::createFolderIndex(QStringList tree) -{ - QModelIndex indexRes; - - QStandardItem *item = invisibleRootItem(); - for (int i = 0; i < tree.size(); ++i) - { - auto indexLst = match(index(0, 0, indexRes), Qt::DisplayRole, tree[i], 1, Qt::MatchExactly); - if (!indexLst.isEmpty()) - { - indexRes = indexLst[0]; - item = itemFromIndex(indexRes); - if (item->data(DATATYPE_ROLE).toInt() == DATATYPE_ROLE_DATASET) - { - item->setData(DATATYPE_ROLE_BOTH, DATATYPE_ROLE); - } - } - else - { - QStandardItem * newItem = new QStandardItem(); - newItem->setData(tree[i], Qt::DisplayRole); - newItem->setData(tree[i], DATANAME_ROLE); - newItem->setData(DATATYPE_ROLE_FOLDER, DATATYPE_ROLE); - item->insertRow(item->rowCount(), newItem); - indexRes = indexFromItem(newItem); - } - } - - return indexRes; -} - -void medVirtualRepresentation::removeTooOldEntry() { //TODO + return false; } -QModelIndex medVirtualRepresentation::getModelIndex(medDataIndex index) -{ - QModelIndex indexRes; - QString indexAsString = indexToFileSysPath(index.asString()); - if (d->uriToJsonPaths.contains(indexAsString)) - { - QString jsonPath = d->uriToJsonPaths.value(indexAsString); - indexRes = getIndex(jsonPath); - } - - return indexRes; -} - - +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// +// ////////////// Internal routines section /////// +// /////////////////////////////////////////////////////////////////////////// +// /////////////////////////////////////////////////////////////////////////// + +/** + * @brief Internal function for computing name and placement. + * + * This function is likely used internally by the class and is not intended to be called directly from user code. + * It computes the name and placement of an item based on the provided information. + * + * @param item The QStandardItem object representing the item. + * @param indexAsString A string representation of the medDataIndex. + * @param dataName The name of the data associated with the item. + * @param indexPlace [OUT] An integer reference to store the computed placement of the item. + * @param tmpName [OUT] A string reference to store a temporary name. + */ void medVirtualRepresentation::computeNameAndPlace(QStandardItem * item, const QString indexAsString, const QString &dataName, int &indexPlace, QString &tmpName) { int childCount = item->rowCount(); @@ -846,6 +1056,79 @@ void medVirtualRepresentation::computeNameAndPlace(QStandardItem * item, const Q } while (bAlreadyExist); } +/** + * @brief Internal function for inserting data. + * + * This function is likely used internally by the class and is not intended to be called directly from user code. + * It inserts data into the model, handling aspects like URI, data path, and temporary name. + * + * @param data The medAbstractData object representing the data to insert. + * @param uri [OUT] A string reference to store the URI of the data. + * @param dataPath [OUT] A string reference to store the data path. + * @param tmpName [OUT] A string reference to store a temporary name. + */ +void medVirtualRepresentation::insertData(medAbstractData * data, QString &uri, QString &dataPath, QString &tmpName) +{ + if (data) + { + if (!d->uriToAbstractData.contains(uri)) + { + d->uriToAbstractData[uri] = data; + } + } + d->uriToJsonPaths.insert(uri, dataPath + '/' + tmpName); +} + + +/** + * @brief Internal function for creating a folder index. + * + * This function is likely used internally by the class and is not intended to be called directly from user code. + * It creates a model index for a folder based on a list of strings representing the folder hierarchy. + * + * @param tree A QStringList containing the path components of the folder. + * @return A QModelIndex representing the created folder, or an invalid index if the folder could not be created. + */ +QModelIndex medVirtualRepresentation::createFolderIndex(QStringList tree) +{ + QModelIndex indexRes; + + QStandardItem *item = invisibleRootItem(); + for (int i = 0; i < tree.size(); ++i) + { + auto indexLst = match(index(0, 0, indexRes), Qt::DisplayRole, tree[i], 1, Qt::MatchExactly); + if (!indexLst.isEmpty()) + { + indexRes = indexLst[0]; + item = itemFromIndex(indexRes); + if (item->data(DATATYPE_ROLE).toInt() == DATATYPE_ROLE_DATASET) + { + item->setData(DATATYPE_ROLE_BOTH, DATATYPE_ROLE); + } + } + else + { + QStandardItem * newItem = new QStandardItem(); + newItem->setData(tree[i], Qt::DisplayRole); + newItem->setData(tree[i], DATANAME_ROLE); + newItem->setData(DATATYPE_ROLE_FOLDER, DATATYPE_ROLE); + item->insertRow(item->rowCount(), newItem); + indexRes = indexFromItem(newItem); + } + } + + return indexRes; +} + +/** + * @brief Gets the path associated with a model index. + * + * This function retrieves the path associated with a given model index. + * It likely traverses the model hierarchy to construct the path. + * + * @param index The model index (default = current index). (default = QModelIndex()) + * @return A string representing the path associated with the model index, or an empty string if the path cannot be determined. + */ QString medVirtualRepresentation::getPath(QModelIndex index) { QString resPath = d->basePath.value().replace('\\', '/'); @@ -865,15 +1148,24 @@ QString medVirtualRepresentation::getPath(QModelIndex index) return resPath; } -QModelIndex medVirtualRepresentation::getIndex(QString path) +/** + * @brief Gets the model index for a JSON path. + * + * This function is likely used internally by the class and is not intended to be called directly from user code. + * It retrieves a model index based on a path specified in JSON format. + * + * @param jsonPath A string representing the JSON path. + * @return A QModelIndex representing the item at the specified JSON path, or an invalid index if the path is invalid. + */ +QModelIndex medVirtualRepresentation::getIndex(QString jsonPath) { QModelIndex indexRes; QString basePath = d->basePath.value(); - if (path.startsWith(basePath)) + if (jsonPath.startsWith(basePath)) { - path.remove(0, basePath.length()); - QStringList pathSplited = path.split('/'); + jsonPath.remove(0, basePath.length()); + QStringList pathSplited = jsonPath.split('/'); QModelIndex indexTmp; for (int i = 0; i < pathSplited.size(); ++i) @@ -889,3 +1181,31 @@ QModelIndex medVirtualRepresentation::getIndex(QString path) return indexRes; } + +/** + * @brief Removes data entries that are considered too old. + * + * This function likely iterates through cached, stored data entries, JSON files and removes those that are considered outdated based on some criteria. + * This helps with managing storage space and keeping the data fresh. + */ +void medVirtualRepresentation::removeTooOldEntry() +{ + //TODO +} + +/** + * @brief Private slot for renaming an item based on the item object. + * + * This function is a private slot, meaning it can only be invoked from signals emitted within the class. + * The connect is into the constructor. + * It renames an item in the model based on information retrieved from the QStandardItem object itself. + * + * @param item The QStandardItem object representing the item to rename. + */ +void medVirtualRepresentation::renameByItem(QStandardItem * item) +{ + QModelIndex index = indexFromItem(item); + QString name = item->data(Qt::DisplayRole).toString(); + + rename(index, name); +} diff --git a/src/layers/medCore/source/virtualRepresentation/medVirtualRepresentation.h b/src/layers/medCore/source/virtualRepresentation/medVirtualRepresentation.h index e2af41e39f..ed87b94afa 100644 --- a/src/layers/medCore/source/virtualRepresentation/medVirtualRepresentation.h +++ b/src/layers/medCore/source/virtualRepresentation/medVirtualRepresentation.h @@ -6,6 +6,9 @@ #include #include +/** + * @brief Defines several constants used throughout the class. + */ #define DATAORIGIN_ROLE 200 //String defined as below #define DATAORIGIN_ROLE_FILESYSTEM "FS" #define DATAORIGIN_ROLE_SOURCE "source" @@ -13,15 +16,13 @@ #define DATAURI_ROLE 201 //String URI of the data #define DATAGARBAGEABLE_ROLE 202 //Boolean indicates if the data can be automatically removed (if longtime or too much data) -//#define DATAISDIRECTORY_ROLE 203 //Boolean indicates if an item is a pure directory #define DATANAME_ROLE 300 -#define INVALID_ENTRY "invalidEntry.json" - class medVirtualRepresentationPrivate; + /** - * @brief medVirtualRepresentation centralise toutes les données ouvertes dans medInria et elle assure aussi l'organization des données pour l'utilisateur. + * @brief The medVirtualRepresentation class centralizes all data opened in medInria and also ensures the organization of data for the user. */ class MEDCORE_EXPORT medVirtualRepresentation : public QStandardItemModel { @@ -30,69 +31,86 @@ class MEDCORE_EXPORT medVirtualRepresentation : public QStandardItemModel medVirtualRepresentation(QObject *parent = nullptr); ~medVirtualRepresentation(); - bool readFileEntry(QString filePath, QString &dataOrigine, QString &dataURI, bool &dataGarbadgeable); - bool writeFileEntry(QJsonObject const & entry, QString filePath, QString fileName); - bool remove(QModelIndex index); bool rename(QModelIndex index, QString newName); bool create(QModelIndex parent, QString dirName); - bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; QMimeData * mimeData(const QModelIndexList &indexes) const override; QStringList mimeTypes() const override; Qt::DropActions supportedDropActions() const override; + QModelIndex getModelIndex(medDataIndex index); QList getParams(); - QModelIndex getModelIndex(medDataIndex index); + +public slots: + void addGeneratedData(medAbstractData * data, QString name = ""); + void addData(medDataIndex medIndex, QString volumeName = "", medAbstractData * data = nullptr, const QModelIndex & parent = QModelIndex()); + + void pinData (QModelIndex modelIndex); + void unPinData (QModelIndex modelIndex); + void removeData(QModelIndex modelIndex); + + void dataSaved(medDataIndex index); //remove a cache data and replace it by an uri on the source private: + // JSon handling section bool fetch(QString const &path = QString()); - + bool readFileEntry(QString filePath, QString &dataOrigine, QString &dataURI, bool &dataGarbadgeable); + bool writeFileEntry(QJsonObject const & entry, QString filePath, QString fileName); bool writeJson(const QModelIndex & index, QJsonObject &json); bool readJson (const QByteArray & array, QString &dataOrigine, QString &dataURI, bool &dataGarbadgeable); - void computeNameAndPlace(QStandardItem * item, const QString indexAsString, const QString &dataName, int &indexPlace, QString &tmpName); - - QString getPath(QModelIndex index = QModelIndex()); - QModelIndex getIndex(QString path); + // File system handling for json section bool createFSDirectory(QString path, QString dirName); bool renameFSEntry (QString path); bool removeFSDir (QString path); bool removeFSFile (QString path); bool moveFSEntry (QString oldPath, QString newPath); - + + // Cache section bool writeCacheData(medAbstractData * data, QString path, QString name); bool readCacheData (medAbstractData *& data, QString path, QString name); + // Internal routines section + void computeNameAndPlace(QStandardItem * item, const QString indexAsString, const QString &dataName, int &indexPlace, QString &tmpName); + void insertData(medAbstractData * data, QString &uri, QString &dataPath, QString &tmpName); QModelIndex createFolderIndex(QStringList tree); + QString getPath(QModelIndex index = QModelIndex()); + QModelIndex getIndex(QString jsonPath); void removeTooOldEntry(); - -public slots: - void dataSaved(medDataIndex index); //remove a cache data and replace it by an uri on the source - - void addGeneratedData(medAbstractData * data, QString name = ""); - void addDataFromSource(medDataIndex index, medAbstractData * data = nullptr, const QModelIndex & parent = QModelIndex()); - void addDataFromFile(QString path, medAbstractData * data = nullptr, const QModelIndex & parent = QModelIndex()); - - void pinData (QModelIndex modelIndex); - void unPinData (QModelIndex modelIndex); - void removeData(QModelIndex modelIndex); - private slots: void renameByItem(QStandardItem * item); - signals: + /** + * @brief Signal emitted when an index is edited. + * @param index The edited index. + */ void editIndex(QModelIndex const &); + + /** + * @brief Signal emitted when data is expanded. + * @param index The index of the expanded data. + * @param state The expansion state (true for expanded, false for collapsed). + */ void expandData(QModelIndex const &, bool); - void visibility (); + + /** + * @brief Signal emitted when the visibility changes. + */ + void visibility(); + + /** + * @brief Signal emitted when the visibility state changes. + * @param state The new visibility state. + */ void visibled(bool state); diff --git a/src/layers/medCoreGui/CMakeLists.txt b/src/layers/medCoreGui/CMakeLists.txt index f011e22683..2a1a567118 100644 --- a/src/layers/medCoreGui/CMakeLists.txt +++ b/src/layers/medCoreGui/CMakeLists.txt @@ -76,10 +76,10 @@ target_include_directories(${TARGET_NAME} ## ############################################################################# target_link_libraries(${TARGET_NAME} PUBLIC - Qt5::Core - Qt5::Widgets - Qt5::Test - Qt5::Xml + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Test + Qt${QT_VERSION_MAJOR}::Xml med::Core @@ -106,5 +106,5 @@ set_lib_install_rules(${TARGET_NAME} PUBLIC_DEPENDENCIES "medInria REQUIRED COMPONENTS Core" "dtk REQUIRED COMPONENTS dtkCore dtkLog dtkCoreSupport dtkGuiSupport" - "Qt5 REQUIRED COMPONENTS Core Xml Widgets Test" + "Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Xml Widgets Test" ) diff --git a/src/layers/medCoreGui/toolboxes/medDiffusionSelectorToolBox.cpp b/src/layers/medCoreGui/toolboxes/medDiffusionSelectorToolBox.cpp index 240d8b8977..31e045469c 100644 --- a/src/layers/medCoreGui/toolboxes/medDiffusionSelectorToolBox.cpp +++ b/src/layers/medCoreGui/toolboxes/medDiffusionSelectorToolBox.cpp @@ -301,8 +301,8 @@ void medDiffusionSelectorToolBox::addInputImage(medAbstractImageData *data) this->setEnabled(true); d->inputsMap[dataId.toString()] = data; - d->chooseInput->addItem(data->metadata(medMetaDataKeys::SeriesDescription.key()),dataId.toString()); - d->chooseInput->setToolTip(data->metadata(medMetaDataKeys::SeriesDescription.key())); + d->chooseInput->addItem(data->fecthMetaData("SeriesDescription"), dataId.toString()); + d->chooseInput->setToolTip(data->fecthMetaData("SeriesDescription")); d->chooseInput->setCurrentIndex(d->chooseInput->count() - 1); } diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 1ee2500734..a6699074bb 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -76,7 +76,7 @@ set(PLUGIN_LIST legacy/vtkDataMesh ON legacy/medExportVideo ON legacy/medSQLite ON - # legacy/medShanoir ON + legacy/medShanoir ON # legacy/medAPHPDataSource ON legacy/medPACS ON legacy/medTemporaryDataSource ON diff --git a/src/plugins/legacy/LCCLogDemons/CMakeLists.txt b/src/plugins/legacy/LCCLogDemons/CMakeLists.txt index bece7a0eb2..cf936d6101 100644 --- a/src/plugins/legacy/LCCLogDemons/CMakeLists.txt +++ b/src/plugins/legacy/LCCLogDemons/CMakeLists.txt @@ -24,7 +24,7 @@ if (UNIX AND NOT APPLE) set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,ALL") endif() -#find_package(Qt5 COMPONENTS REQUIRED Core) +#find_package(Qt${QT_VERSION_MAJOR} COMPONENTS REQUIRED Core) find_package(dtk REQUIRED) include_directories(${dtk_INCLUDE_DIRS}) @@ -99,7 +99,7 @@ SET(ITKIO_LIBRARIES target_link_libraries(${TARGET_NAME} ${ITKIO_LIBRARIES} ITKPDEDeformableRegistration - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkLog dtkCoreSupport medCore diff --git a/src/plugins/legacy/diffeomorphicDemons/CMakeLists.txt b/src/plugins/legacy/diffeomorphicDemons/CMakeLists.txt index 89f12cf300..f665105b2f 100644 --- a/src/plugins/legacy/diffeomorphicDemons/CMakeLists.txt +++ b/src/plugins/legacy/diffeomorphicDemons/CMakeLists.txt @@ -27,7 +27,7 @@ add_definitions(-D${TARGET_NAME_UP}_VERSION="${${TARGET_NAME}_VERSION}") ## ############################################################################# ## Resolve dependencies ## ############################################################################# -find_package(Qt5 REQUIRED COMPONENTS Quick Xml Test) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Quick Xml Test) if(NOT TARGET medCore) find_package(medInria REQUIRED COMPONENTS Core Registration) diff --git a/src/plugins/legacy/examples/ITKProcessExample/CMakeLists.txt b/src/plugins/legacy/examples/ITKProcessExample/CMakeLists.txt index 404fd1c712..8bd2e7cb7d 100644 --- a/src/plugins/legacy/examples/ITKProcessExample/CMakeLists.txt +++ b/src/plugins/legacy/examples/ITKProcessExample/CMakeLists.txt @@ -29,7 +29,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR TRUE) ## ################################################################# ## Resolve dependencies ## ################################################################# -find_package(Qt5 REQUIRED COMPONENTS Quick Xml Test) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Quick Xml Test) find_package(medInria REQUIRED COMPONENTS Core) diff --git a/src/plugins/legacy/iterativeClosestPoint/iterativeClosestPointToolBox.cpp b/src/plugins/legacy/iterativeClosestPoint/iterativeClosestPointToolBox.cpp index 8ff2a41e79..2bd398e664 100644 --- a/src/plugins/legacy/iterativeClosestPoint/iterativeClosestPointToolBox.cpp +++ b/src/plugins/legacy/iterativeClosestPoint/iterativeClosestPointToolBox.cpp @@ -282,7 +282,8 @@ void iterativeClosestPointToolBox::addLayer(unsigned int layer) { medAbstractData *data = d->currentView->layerData(layer); - QString name = medMetaDataKeys::SeriesDescription.getFirstValue(data,"no name"); + QString name = data->fecthMetaData("SeriesDescription"); + if (name.isEmpty()) name = "no name"; if(data && (data->identifier().contains("vtkDataMesh") || data->identifier().contains("EPMap"))) diff --git a/src/plugins/legacy/itkDataImage/CMakeLists.txt b/src/plugins/legacy/itkDataImage/CMakeLists.txt index a966b3a8f8..dfa0e7e5c8 100644 --- a/src/plugins/legacy/itkDataImage/CMakeLists.txt +++ b/src/plugins/legacy/itkDataImage/CMakeLists.txt @@ -133,8 +133,8 @@ target_include_directories(${TARGET_NAME} ## ############################################################################# target_link_libraries(${TARGET_NAME} - Qt5::Core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets dtkCore dtkLog gdcmCommon diff --git a/src/plugins/legacy/itkDataImage/interactors/medVtkViewItkDataImage4DInteractor.cpp b/src/plugins/legacy/itkDataImage/interactors/medVtkViewItkDataImage4DInteractor.cpp index 17967c2c38..a6b63fd072 100644 --- a/src/plugins/legacy/itkDataImage/interactors/medVtkViewItkDataImage4DInteractor.cpp +++ b/src/plugins/legacy/itkDataImage/interactors/medVtkViewItkDataImage4DInteractor.cpp @@ -122,8 +122,8 @@ void medVtkViewItkDataImage4DInteractor::setInputData(medAbstractData *data) if (SetViewInput(data, layer) ) { - d->imageData->setMetaData("SequenceDuration", QString::number(m_poConv->getTotalTime())); - d->imageData->setMetaData("SequenceFrameRate", QString::number((double)(m_poConv->getNumberOfVolumes() -1 )/ (double)m_poConv->getTotalTime())); + d->imageData->setMetaData(QString("SequenceDuration"), QString::number(m_poConv->getTotalTime())); + d->imageData->setMetaData(QString("SequenceFrameRate"), QString::number((double)(m_poConv->getNumberOfVolumes() -1 )/ (double)m_poConv->getTotalTime())); qDebug() << "SequenceDuration" << m_poConv->getTotalTime(); qDebug() << "SequenceFrameRate" <<(double)(m_poConv->getNumberOfVolumes() -1)/ m_poConv->getTotalTime(); diff --git a/src/plugins/legacy/itkDataImage/readers/itkDCMTKDataImageReader.cpp b/src/plugins/legacy/itkDataImage/readers/itkDCMTKDataImageReader.cpp index 105d03135a..7696846e67 100644 --- a/src/plugins/legacy/itkDataImage/readers/itkDCMTKDataImageReader.cpp +++ b/src/plugins/legacy/itkDataImage/readers/itkDCMTKDataImageReader.cpp @@ -385,66 +385,20 @@ bool itkDCMTKDataImageReader::readInformation(const QStringList& paths) { valueList << QString::fromStdString(val); } - - medData->setMetaData(QString::fromStdString(key), valueList); + int x = 0; + if (key == "(0008,103E)" | key == "(0010,0010)" | key == "(0010,0020)" | key == "(0008,103e)") + { + x = 200; + } + QString s = valueList[0]; + if (s.toLower().trimmed().contains("phil")) + { + x = 300; + } + Key2 k = medMetaDataKeys::keyFromTag(QString::fromStdString(key), "dicom"); + medData->setMetaData(QString::fromStdString(key), valueList[0]); } - // PATIENT - //PatientId - medData->setMetaData(medMetaDataKeys::PatientName.key(), QString::fromLatin1(d->io->GetPatientName().c_str())); - medData->setMetaData(medMetaDataKeys::Age.key(), d->io->GetPatientAge().c_str()); - medData->setMetaData(medMetaDataKeys::BirthDate.key(), d->io->GetPatientDOB().c_str()); - medData->setMetaData(medMetaDataKeys::Gender.key(), d->io->GetPatientSex().c_str()); - medData->setMetaData(medMetaDataKeys::PatientID.key(), QString::fromLatin1(d->io->GetPatientID().c_str())); - medData->setMetaData(medMetaDataKeys::Description.key(), QString::fromLatin1(d->io->GetScanOptions().c_str())); - - // STUDY - //StudyId - medData->setMetaData(medMetaDataKeys::StudyID.key(), QString::fromLatin1(d->io->GetStudyID().c_str())); - medData->setMetaData(medMetaDataKeys::StudyInstanceUID.key(), d->io->GetStudyInstanceUID().c_str()); - medData->setMetaData(medMetaDataKeys::StudyDescription.key(), QString::fromLatin1(d->io->GetStudyDescription().c_str())); - medData->setMetaData(medMetaDataKeys::Institution.key(), QString::fromLatin1(d->io->GetInstitution().c_str())); - medData->setMetaData(medMetaDataKeys::Referee.key(), QString::fromLatin1(d->io->GetReferringPhysicianName().c_str())); - //StudyDate - //StudyTime - - // SERIES - //SeriesID - medData->setMetaData(medMetaDataKeys::SeriesInstanceUID.key(), d->io->GetSeriesInstanceUID().c_str()); - medData->setMetaData(medMetaDataKeys::SeriesNumber.key(), d->io->GetSeriesNumber().c_str()); - medData->setMetaData(medMetaDataKeys::Modality.key(), d->io->GetModality().c_str()); - medData->setMetaData(medMetaDataKeys::Performer.key(), QString::fromLatin1(d->io->GetPerformingPhysicianName().c_str())); - medData->setMetaData(medMetaDataKeys::Report.key(), ""); - medData->setMetaData(medMetaDataKeys::Protocol.key(), QString::fromLatin1(d->io->GetProtocolName().c_str())); - medData->setMetaData(medMetaDataKeys::SeriesDescription.key(), QString::fromLatin1(d->io->GetSeriesDescription().c_str())); - //SeriesDate - //SeriesTime - //SeriesThumbnail - - // IMAGE - //SOPInstanceUID - medData->setMetaData(medMetaDataKeys::Columns.key(), d->io->GetColumns().c_str()); - medData->setMetaData(medMetaDataKeys::Rows.key(), d->io->GetRows().c_str()); - //Dimensions - //NumberOfDimensions - medData->setMetaData(medMetaDataKeys::Orientation.key(), d->io->GetOrientation().c_str()); - - // Patient position - std::string patientPos = d->io->GetMetaDataValueString("(0018,5100)", 0); - medData->setMetaData(medMetaDataKeys::PatientPosition.key(), patientPos.c_str()); - // Patient orientation - std::string patientOrient = d->io->GetMetaDataValueString("(0020,0020)", 0); - medData->setMetaData(medMetaDataKeys::PatientOrientation.key(), patientOrient.c_str()); - - // Image Type - QString imageType = QString::fromStdString(d->io->GetMetaDataValueString("(0008,0008)", 0)); - // it seems '\' characters are replaced by whitespaces. This is not correct - // for this tag. - imageType = imageType.replace(' ', "\\"); - medData->setMetaData(medMetaDataKeys::ImageType.key(), imageType.toStdString().c_str()); - - // Acquisition number - std::string acquisitionNumber = d->io->GetMetaDataValueString("(0020,0012)", 0); - medData->setMetaData(medMetaDataKeys::AcquisitionNumber.key(), acquisitionNumber.c_str()); + // Add Origin QString origin = ""; @@ -452,14 +406,9 @@ bool itkDCMTKDataImageReader::readInformation(const QStringList& paths) { origin += QString::number(d->io->GetOrigin(i)) + QString(" "); } - medData->setMetaData(medMetaDataKeys::Origin.key(), origin.trimmed()); - - medData->setMetaData(medMetaDataKeys::SliceThickness.key(), d->io->GetSliceThickness().c_str()); - //ImportationDate - medData->setMetaData(medMetaDataKeys::AcquisitionDate.key(), d->io->GetAcquisitionDate().c_str()); - medData->setMetaData(medMetaDataKeys::AcquisitionTime.key(), d->io->GetAcquisitionTime().c_str()); - medData->setMetaData(medMetaDataKeys::Comments.key(), QString::fromLatin1(d->io->GetAcquisitionComments().c_str())); + medData->setMetaData(medMetaDataKeys::key("Origin"), origin.trimmed()); + QStringList filePaths; for (unsigned int i = 0; i < d->io->GetOrderedFileNames().size(); i++) { @@ -469,47 +418,7 @@ bool itkDCMTKDataImageReader::readInformation(const QStringList& paths) } } - medData->addMetaData(medMetaDataKeys::FilePaths.key(), filePaths); - - medData->setMetaData(medMetaDataKeys::Status.key(), d->io->GetPatientStatus().c_str()); - medData->setMetaData(medMetaDataKeys::SequenceName.key(), QString::fromLatin1(d->io->GetSequenceName().c_str())); - //Size - //VolumeUID - //Spacing - //XSpacing - //YSpacing - //ZSpacing - //NumberOfComponents - //ComponentType - //PixelType - //medDataType - //PreferredDataReader - //ImageID - //ThumbnailPath - - QString modality = medData->metadata(medMetaDataKeys::Modality.key()); - if (modality.contains("CT")) - { - std::string kvp = d->io->GetMetaDataValueString("(0018,0060)", 0 ); - medData->setMetaData(medMetaDataKeys::KVP.key(), kvp.c_str()); - } - else if (modality.contains("MR")) - { - // MR Image - medData->setMetaData(medMetaDataKeys::FlipAngle.key(), d->io->GetFlipAngle().c_str()); - medData->setMetaData(medMetaDataKeys::EchoTime.key(), d->io->GetEchoTime().c_str()); - medData->setMetaData(medMetaDataKeys::RepetitionTime.key(), d->io->GetRepetitionTime().c_str()); - } - - // Frame of reference - std::string frameOfRef = d->io->GetMetaDataValueString("(0020,0052)", 0); - medData->setMetaData(medMetaDataKeys::FrameOfReferenceUID.key(), frameOfRef.c_str()); - std::string posRefIndicator = d->io->GetMetaDataValueString("(0020,1040)", 0); - medData->setMetaData(medMetaDataKeys::PositionReferenceIndicator.key(), posRefIndicator.c_str()); - - // Equipement - std::string manufacturer = d->io->GetMetaDataValueString("(0008,0070)", 0); - medData->setMetaData(medMetaDataKeys::Manufacturer.key(), manufacturer.c_str()); + medData->addMetaData(medMetaDataKeys::key("FilePaths"), filePaths); } else { @@ -588,7 +497,11 @@ bool itkDCMTKDataImageReader::read(const QStringList& paths) const StringVectorType &values = metaData->GetMetaDataObjectValue(); for (unsigned int i = 0; i < values.size(); i++) { - medData->addMetaData(it->first.c_str(), values[i].c_str()); + bool bHasMetaData = medData->hasMetaData(it->first.c_str()); + if (!bHasMetaData || bHasMetaData && medData->metadata(it->first.c_str()).isEmpty()) + { + medData->setMetaData(it->first.c_str(), values[i].c_str()); + } } } ++it; @@ -606,6 +519,18 @@ void itkDCMTKDataImageReader::setProgress(int value) emit progressed(value); qApp->processEvents(); } +QString itkDCMTKDataImageReader::getVolumeId(const QString& path) +{ + this->readInformation(path); + return QString::fromStdString(d->io->GetSeriesInstanceUID()); +} + +QString itkDCMTKDataImageReader::getVolumeName(const QString& path) +{ + this->readInformation(path); + return QString::fromStdString(d->io->GetSeriesDescription()); +} + // ///////////////////////////////////////////////////////////////// // Type instantiation // ///////////////////////////////////////////////////////////////// diff --git a/src/plugins/legacy/itkDataImage/readers/itkDCMTKDataImageReader.h b/src/plugins/legacy/itkDataImage/readers/itkDCMTKDataImageReader.h index 543b634ccc..5b0fd59898 100644 --- a/src/plugins/legacy/itkDataImage/readers/itkDCMTKDataImageReader.h +++ b/src/plugins/legacy/itkDataImage/readers/itkDCMTKDataImageReader.h @@ -50,6 +50,9 @@ public slots: void setProgress (int value); + QString getVolumeId(const QString& path); + QString getVolumeName(const QString& path); + private: itkDCMTKDataImageReaderPrivate *d; diff --git a/src/plugins/legacy/itkDataImage/readers/itkGDCMDataImageReader.cpp b/src/plugins/legacy/itkDataImage/readers/itkGDCMDataImageReader.cpp index cb31136f5c..6ae4f0f6e5 100644 --- a/src/plugins/legacy/itkDataImage/readers/itkGDCMDataImageReader.cpp +++ b/src/plugins/legacy/itkDataImage/readers/itkGDCMDataImageReader.cpp @@ -374,24 +374,24 @@ bool itkGDCMDataImageReader::readInformation(const QStringList &paths) rows << this->m_Scanner.GetValue(firstfilename.c_str(), gdcm::Tag(0x0028, 0x0010)); columns << this->m_Scanner.GetValue(firstfilename.c_str(), gdcm::Tag(0x0028, 0x0011)); - medData->setMetaData(medMetaDataKeys::PatientName.key(), patientName); - medData->setMetaData(medMetaDataKeys::PatientID.key(), patientName); - medData->setMetaData(medMetaDataKeys::StudyDescription.key(), studyName); - medData->setMetaData(medMetaDataKeys::SeriesDescription.key(), seriesName); - medData->setMetaData(medMetaDataKeys::StudyID.key(), studyId); - medData->setMetaData(medMetaDataKeys::SeriesID.key(), seriesId); - medData->setMetaData(medMetaDataKeys::Orientation.key(), orientation); - medData->setMetaData(medMetaDataKeys::SeriesNumber.key(), seriesNumber); - medData->setMetaData(medMetaDataKeys::SequenceName.key(), sequenceName); - medData->setMetaData(medMetaDataKeys::SliceThickness.key(), sliceThickness); - medData->setMetaData(medMetaDataKeys::Rows.key(), rows); - medData->setMetaData(medMetaDataKeys::Columns.key(), columns); + medData->setMetaData(medMetaDataKeys::key("PatientName"), patientName); + medData->setMetaData(medMetaDataKeys::key("PatientID"), patientName); + medData->setMetaData(medMetaDataKeys::key("StudyDescription"), studyName); + medData->setMetaData(medMetaDataKeys::key("SeriesDescription"), seriesName); + medData->setMetaData(medMetaDataKeys::key("StudyID"), studyId); + medData->setMetaData(medMetaDataKeys::key("SeriesID"), seriesId); + medData->setMetaData(medMetaDataKeys::key("Orientation"), orientation); + medData->setMetaData(medMetaDataKeys::key("SeriesNumber"), seriesNumber); + medData->setMetaData(medMetaDataKeys::key("SequenceName"), sequenceName); + medData->setMetaData(medMetaDataKeys::key("SliceThickness"), sliceThickness); + medData->setMetaData(medMetaDataKeys::key("Rows"), rows); + medData->setMetaData(medMetaDataKeys::key("Columns"), columns); FileList orderedfilelist = this->unfoldMap(map); for (unsigned int i=0; iaddMetaData(medMetaDataKeys::FilePaths.key(),filePaths); + medData->addMetaData(medMetaDataKeys::key("FilePaths"),filePaths); } return true; @@ -661,6 +661,18 @@ void itkGDCMDataImageReader::setProgress (int value) emit progressed (value); } +QString itkGDCMDataImageReader::getVolumeId(const QString& path) +{ + this->readInformation(path.toUtf8().data()); + return this->m_Scanner.GetValue(path.toUtf8().data(), gdcm::Tag(0x0020, 0x000e)); +} + +QString itkGDCMDataImageReader::getVolumeName(const QString& path) +{ + this->readInformation(path.toUtf8().data()); + return this->m_Scanner.GetValue(path.toUtf8().data(), gdcm::Tag(0x0008, 0x103e)); +} + // ///////////////////////////////////////////////////////////////// // Type instantiation // ///////////////////////////////////////////////////////////////// diff --git a/src/plugins/legacy/itkDataImage/readers/itkGDCMDataImageReader.h b/src/plugins/legacy/itkDataImage/readers/itkGDCMDataImageReader.h index 49d88f7d8f..1d5f42cf7d 100644 --- a/src/plugins/legacy/itkDataImage/readers/itkGDCMDataImageReader.h +++ b/src/plugins/legacy/itkDataImage/readers/itkGDCMDataImageReader.h @@ -67,6 +67,9 @@ public slots: void setProgress (int value); + QString getVolumeId(const QString& path); + QString getVolumeName(const QString& path); + private: FileListMapType sort (FileList filelist); diff --git a/src/plugins/legacy/itkDataImage/writers/dicomRtImageWriter.cpp b/src/plugins/legacy/itkDataImage/writers/dicomRtImageWriter.cpp index d97b84ab76..feff9cb7e7 100644 --- a/src/plugins/legacy/itkDataImage/writers/dicomRtImageWriter.cpp +++ b/src/plugins/legacy/itkDataImage/writers/dicomRtImageWriter.cpp @@ -71,7 +71,7 @@ void DicomRtImageWriter::fillDictionaryFromMetaDataKey(itk::MetaDataDictionary& QStringList metaDataList = this->data()->metaDataList(); // Image Type - if (!metaDataList.contains(medMetaDataKeys::ImageType.key())) + if (!metaDataList.contains(medMetaDataKeys::key("ImageType"))) { // our data did not have an Image Type, create a default one: // DERIVED: pixel values have been derived from one or more @@ -82,10 +82,10 @@ void DicomRtImageWriter::fillDictionaryFromMetaDataKey(itk::MetaDataDictionary& } // Patient's gender - if (metaDataList.contains(medMetaDataKeys::Gender.key())) + if (metaDataList.contains(medMetaDataKeys::key("Gender"))) { // check the value - QString gender = this->data()->metaDataValues(medMetaDataKeys::Gender.key()).first(); + QString gender = this->data()->metaDataValues(medMetaDataKeys::key("Gender")).first(); if (gender != "M" && gender != "F" && gender != "O") { // Anonymized or invalid gender, use default diff --git a/src/plugins/legacy/itkDataImage/writers/itkDicomDataImageWriter.cpp b/src/plugins/legacy/itkDataImage/writers/itkDicomDataImageWriter.cpp index 8bbc0f8d91..660ac23eff 100644 --- a/src/plugins/legacy/itkDataImage/writers/itkDicomDataImageWriter.cpp +++ b/src/plugins/legacy/itkDataImage/writers/itkDicomDataImageWriter.cpp @@ -196,7 +196,7 @@ void itkDicomDataImageWriter::fillDictionaryFromMetaDataKey(itk::MetaDataDiction // Institution Name itk::EncapsulateMetaData(dictionary, "0008|0080", data()->metadata(metaDataKey).toStdString()); } - if (metaDataKey == medMetaDataKeys::AcquisitionNumber.key()) + if (metaDataKey == medMetaDataKeys::key("AcquisitionNumber")) { itk::EncapsulateMetaData(dictionary, "0020|0012", data()->metadata(metaDataKey).toStdString()); } @@ -215,26 +215,26 @@ void itkDicomDataImageWriter::fillDictionaryFromMetaDataKey(itk::MetaDataDiction // Sequence Name itk::EncapsulateMetaData(dictionary, "0018|0024", data()->metadata(metaDataKey).toStdString()); } - if (metaDataKey == medMetaDataKeys::PatientPosition.key()) + if (metaDataKey == medMetaDataKeys::key("PatientPosition")) { // Patient Position itk::EncapsulateMetaData(dictionary, "0018|5100", data()->metadata(metaDataKey).toStdString()); } - if (metaDataKey == medMetaDataKeys::PatientOrientation.key()) + if (metaDataKey == medMetaDataKeys::key("PatientOrientation")) { // Patient Orientation itk::EncapsulateMetaData(dictionary, "0020|0020", data()->metadata(metaDataKey).toStdString()); } - if (metaDataKey == medMetaDataKeys::ImageType.key()) + if (metaDataKey == medMetaDataKeys::key("ImageType")) { // Image type itk::EncapsulateMetaData(dictionary, "0008|0008", data()->metadata(metaDataKey).toStdString()); } - if (metaDataKey == medMetaDataKeys::PositionReferenceIndicator.key()) + if (metaDataKey == medMetaDataKeys::key("PositionReferenceIndicator")) { itk::EncapsulateMetaData(dictionary, "0020|1040", data()->metadata(metaDataKey).toStdString()); } - if (metaDataKey == medMetaDataKeys::Manufacturer.key()) + if (metaDataKey == medMetaDataKeys::key("Manufacturer")) { itk::EncapsulateMetaData(dictionary, "0008|0070", data()->metadata(metaDataKey).toStdString()); } @@ -243,7 +243,7 @@ void itkDicomDataImageWriter::fillDictionaryFromMetaDataKey(itk::MetaDataDiction void itkDicomDataImageWriter::fillDictionaryWithModalityDependentData(itk::MetaDataDictionary& dictionary) { - QString modality = data()->metadata(medMetaDataKeys::Modality.key()); + QString modality = data()->metadata("Modality"); if (modality.contains("MR")) { itk::EncapsulateMetaData(dictionary, "0018|0081", data()->metadata("EchoTime").toStdString()); @@ -327,7 +327,7 @@ template void itkDicomDataImageWriter::fillDictionaryWithShare itk::EncapsulateMetaData(dictionary,"0020|000e", seriesUID); // Frame of Reference - std::string frameOfRef = data()->metadata(medMetaDataKeys::FrameOfReferenceUID.key()).toStdString(); + std::string frameOfRef = data()->metadata("FrameOfReferenceUID").toStdString(); if (frameOfRef.empty()) { // create a new frame of reference UID diff --git a/src/plugins/legacy/itkDataSHImage/CMakeLists.txt b/src/plugins/legacy/itkDataSHImage/CMakeLists.txt index a575546ebd..eaff38a08b 100644 --- a/src/plugins/legacy/itkDataSHImage/CMakeLists.txt +++ b/src/plugins/legacy/itkDataSHImage/CMakeLists.txt @@ -37,10 +37,6 @@ include(${ITK_USE_FILE}) find_package(VTK REQUIRED COMPONENTS CommonExecutionModel RenderingCore InteractionWidgets) -if (APPLE OR WIN32) - find_package(Boost REQUIRED) -endif() - ## ############################################################################# ## List Sources ## ############################################################################# @@ -65,7 +61,6 @@ list_header_directories_to_include(${TARGET_NAME} include_directories(${${TARGET_NAME}_INCLUDE_DIRS} ${MEDINRIA_INCLUDE_DIRS} - ${Boost_INCLUDE_DIR} ) diff --git a/src/plugins/legacy/itkDataSHImage/management/vtkSphericalHarmonicSource.cxx b/src/plugins/legacy/itkDataSHImage/management/vtkSphericalHarmonicSource.cxx index 289d47b808..47eb6ce94d 100644 --- a/src/plugins/legacy/itkDataSHImage/management/vtkSphericalHarmonicSource.cxx +++ b/src/plugins/legacy/itkDataSHImage/management/vtkSphericalHarmonicSource.cxx @@ -11,45 +11,23 @@ =========================================================================*/ -#include -#include #include #include -#include -#include #include #include #include -#include #include #include #include #include #include -#include - -// Compute spherical associated Legendre function -#if (defined __APPLE__ || defined WIN32 || defined CLANG) -#include -#else -#include -#endif //WIN32 - -#if (defined __APPLE__ || defined WIN32 || defined CLANG) -double sphLegendre(const int l,const int m,const double theta) { - const unsigned lmm = l-m; - const unsigned lpm = l+m; - const double fact = boost::math::factorial(lmm)/boost::math::factorial(lpm); - const double factor = static_cast(2*l+1) * fact / (4.0 * vtkMath::Pi()); - return sqrt(factor)*boost::math::legendre_p(l,m,cos(theta)); -} -#else -double sphLegendre(const int l,const int m,const double theta) { - return std::tr1::sph_legendre(l,m,theta); + +double sphLegendre(const int l,const int m,const double theta) +{ + return std::sph_legendre(l,m,theta); } -#endif //WIN32 typedef itk::Vector itkVector3; diff --git a/src/plugins/legacy/itkINRDataImageReader/CMakeLists.txt b/src/plugins/legacy/itkINRDataImageReader/CMakeLists.txt index e744f84244..c833def6cc 100644 --- a/src/plugins/legacy/itkINRDataImageReader/CMakeLists.txt +++ b/src/plugins/legacy/itkINRDataImageReader/CMakeLists.txt @@ -100,7 +100,7 @@ target_include_directories(${TARGET_NAME} ## ############################################################################# target_link_libraries(${TARGET_NAME} - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core ITKCommon ${ITKIO_LIBRARIES} medImageIO diff --git a/src/plugins/legacy/itkINRDataImageWriter/CMakeLists.txt b/src/plugins/legacy/itkINRDataImageWriter/CMakeLists.txt index c896524804..d54d1f387d 100644 --- a/src/plugins/legacy/itkINRDataImageWriter/CMakeLists.txt +++ b/src/plugins/legacy/itkINRDataImageWriter/CMakeLists.txt @@ -100,7 +100,7 @@ target_include_directories(${TARGET_NAME} ## ############################################################################# target_link_libraries(${TARGET_NAME} - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core ITKCommon ${ITKIO_LIBRARIES} medImageIO diff --git a/src/plugins/legacy/itkProcessRegistrationOptimus/CMakeLists.txt b/src/plugins/legacy/itkProcessRegistrationOptimus/CMakeLists.txt index a2a18ee31c..88bf549f82 100644 --- a/src/plugins/legacy/itkProcessRegistrationOptimus/CMakeLists.txt +++ b/src/plugins/legacy/itkProcessRegistrationOptimus/CMakeLists.txt @@ -95,7 +95,7 @@ SET(ITKIO_LIBRARIES ) target_link_libraries(${TARGET_NAME} - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkLog dtkCoreSupport medCore diff --git a/src/plugins/legacy/medAPHPDataSource/CMakeLists.txt b/src/plugins/legacy/medAPHPDataSource/CMakeLists.txt index 903b2001f9..7ef523a5ba 100644 --- a/src/plugins/legacy/medAPHPDataSource/CMakeLists.txt +++ b/src/plugins/legacy/medAPHPDataSource/CMakeLists.txt @@ -31,7 +31,7 @@ add_definitions(-D${TARGET_NAME_UP}_VERSION="${${TARGET_NAME}_VERSION}") #enable_testing(true) #FIND_PACKAGE(GTest REQUIRED) -#FIND_PACKAGE(Qt5Test REQUIRED) +#FIND_PACKAGE(Qt${QT_VERSION_MAJOR}Test REQUIRED) find_package(DCMTK REQUIRED) @@ -134,7 +134,7 @@ target_link_libraries(${TARGET_NAME} #target_sources(${TARGET_NAME_QTEST} PUBLIC medAPHP.cpp sphereDicomWeb/medAnnotation.cpp test/medAPHPQTest.cpp) #target_include_directories(${TARGET_NAME_QTEST} PUBLIC "." "./test/") #target_link_libraries(${TARGET_NAME_QTEST} PUBLIC -# Qt5::Test +# Qt${QT_VERSION_MAJOR}::Test # medCore # ${TARGET_NAME} # ${QTDCM_LIBRARIES} diff --git a/src/plugins/legacy/medAlgorithmPaint/medAlgorithmPaintToolBox.cpp b/src/plugins/legacy/medAlgorithmPaint/medAlgorithmPaintToolBox.cpp index 25d3897441..d21681cc59 100644 --- a/src/plugins/legacy/medAlgorithmPaint/medAlgorithmPaintToolBox.cpp +++ b/src/plugins/legacy/medAlgorithmPaint/medAlgorithmPaintToolBox.cpp @@ -823,7 +823,7 @@ void AlgorithmPaintToolBox::import() // output->addParentData(m_imageData); // QString desc = m_imageData->getExpectedName() + "_painted"; // output->setExpectedName(desc); - // output->setMetaData(medMetaDataKeys::SeriesDescription.key(), desc); + // output->setMetaData(medMetaDataKeys::key("SeriesDescription"), desc); // } // medDataManager::instance()->importData(output, false); medDataManager::instance()->importData(output, false); diff --git a/src/plugins/legacy/medBinaryOperation/medBinaryOperatorBase.cpp b/src/plugins/legacy/medBinaryOperation/medBinaryOperatorBase.cpp index 4d2fd26a74..0ac9000239 100644 --- a/src/plugins/legacy/medBinaryOperation/medBinaryOperatorBase.cpp +++ b/src/plugins/legacy/medBinaryOperation/medBinaryOperatorBase.cpp @@ -246,7 +246,7 @@ template int medBinaryOperatorBase::runProce m_output = medAbstractDataFactory::instance()->createSmartPointer("itkDataImageUChar3"); m_output->setData(filter->GetOutput()); - QString derivedDescription = description() + " " + m_inputB->metadata(medMetaDataKeys::SeriesDescription.key()); + QString derivedDescription = description() + " " + m_inputB->fecthMetaData("SeriesDescription"); medUtilities::setDerivedMetaData(m_output, m_inputA, derivedDescription); return medAbstractProcessLegacy::SUCCESS; diff --git a/src/plugins/legacy/medFilteringWorkspaceL/medFilteringWorkspaceL.cpp b/src/plugins/legacy/medFilteringWorkspaceL/medFilteringWorkspaceL.cpp index cde12c0258..d406d37cfb 100644 --- a/src/plugins/legacy/medFilteringWorkspaceL/medFilteringWorkspaceL.cpp +++ b/src/plugins/legacy/medFilteringWorkspaceL/medFilteringWorkspaceL.cpp @@ -127,11 +127,11 @@ void medFilteringWorkspaceL::importProcessOutput() { medAbstractData *inputData(selectorToolBox()->data()); - if (! d->filterOutput->hasMetaData(medMetaDataKeys::SeriesDescription.key())) + if (! d->filterOutput->hasMetaData(medMetaDataKeys::key("SeriesDescription"))) { - QString newSeriesDescription = inputData->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = inputData->fecthMetaData("SeriesDescription"); newSeriesDescription += " filtered"; - d->filterOutput->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + d->filterOutput->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); } for( QString metaData : inputData->metaDataList() ) @@ -148,7 +148,7 @@ void medFilteringWorkspaceL::importProcessOutput() } QString generatedID = QUuid::createUuid().toString().replace("{","").replace("}",""); - d->filterOutput->setMetaData ( medMetaDataKeys::SeriesID.key(), generatedID ); + d->filterOutput->setMetaData ( medMetaDataKeys::key("SeriesID"), generatedID ); medDataManager::instance()->importData(d->filterOutput); diff --git a/src/plugins/legacy/medPACS/CMakeLists.txt b/src/plugins/legacy/medPACS/CMakeLists.txt index d30dca9cea..be826d9e89 100644 --- a/src/plugins/legacy/medPACS/CMakeLists.txt +++ b/src/plugins/legacy/medPACS/CMakeLists.txt @@ -31,7 +31,7 @@ add_definitions(-D${TARGET_NAME_UP}_VERSION="${${TARGET_NAME}_VERSION}") #enable_testing(true) #FIND_PACKAGE(GTest REQUIRED) -#FIND_PACKAGE(Qt5Test REQUIRED) +#FIND_PACKAGE(Qt${QT_VERSION_MAJOR}Test REQUIRED) find_package(dtk REQUIRED) include_directories(${dtk_INCLUDE_DIRS}) diff --git a/src/plugins/legacy/medSQLite/CMakeLists.txt b/src/plugins/legacy/medSQLite/CMakeLists.txt index 5005d15dbc..e86b8a85c5 100644 --- a/src/plugins/legacy/medSQLite/CMakeLists.txt +++ b/src/plugins/legacy/medSQLite/CMakeLists.txt @@ -29,7 +29,7 @@ add_definitions(-D${TARGET_NAME_UP}_VERSION="${${TARGET_NAME}_VERSION}") ## Resolve dependencies ## ############################################################################# -find_package(Qt5 REQUIRED Core) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED Core) find_package(dtk REQUIRED) include_directories(${dtk_INCLUDE_DIRS}) @@ -80,6 +80,7 @@ add_library(${TARGET_NAME} SHARED ${${TARGET_NAME}_PCH} ${${TARGET_NAME}_CFILES} ${${TARGET_NAME}_QRC} + ${${TARGET_NAME}_TEMPLATES} ) @@ -87,8 +88,8 @@ add_library(${TARGET_NAME} SHARED ## Link ## ############################################################################# target_link_libraries(${TARGET_NAME} PUBLIC - Qt5::Core - Qt5::Sql + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Sql medCore ) @@ -106,8 +107,8 @@ target_link_libraries(${TARGET_NAME} PUBLIC # GTest::gtest # GTest::gmock_main # GTest::gmock -# Qt5::Core -# Qt5::Sql +# Qt${QT_VERSION_MAJOR}::Core +# Qt${QT_VERSION_MAJOR}::Sql # medCore # ${TARGET_NAME}) # @@ -116,7 +117,7 @@ target_link_libraries(${TARGET_NAME} PUBLIC # #project(medSQLiteIntegrationQTest LANGUAGES CXX) # -#find_package(Qt5Test REQUIRED) +#find_package(Qt${QT_VERSION_MAJOR}Test REQUIRED) # ##set(CMAKE_INCLUDE_CURRENT_DIR ON) # @@ -127,7 +128,7 @@ target_link_libraries(${TARGET_NAME} PUBLIC #add_executable(medSQLiteIntegrationQTest ${CMAKE_CURRENT_SOURCE_DIR}/test/medSQLiteIntegrationQTest.cpp) #add_test(NAME medSQLiteIntegrationQTest COMMAND medSQLiteIntegrationQTest) # -#target_link_libraries(medSQLiteIntegrationQTest PRIVATE Qt5::Test Qt5::Sql medCore) +#target_link_libraries(medSQLiteIntegrationQTest PRIVATE Qt${QT_VERSION_MAJOR}::Test Qt${QT_VERSION_MAJOR}::Sql medCore) ## ############################################################################# ## Install rules diff --git a/src/plugins/legacy/medShanoir/CMakeLists.txt b/src/plugins/legacy/medShanoir/CMakeLists.txt index 249d95de3c..d062e4540e 100644 --- a/src/plugins/legacy/medShanoir/CMakeLists.txt +++ b/src/plugins/legacy/medShanoir/CMakeLists.txt @@ -24,13 +24,14 @@ set(${TARGET_NAME}_VERSION ${MEDINRIA_VERSION}) string(TOUPPER ${TARGET_NAME} TARGET_NAME_UP) add_definitions(-D${TARGET_NAME_UP}_VERSION="${${TARGET_NAME}_VERSION}") - ## ############################################################################# ## Resolve dependencies ## ############################################################################# -find_package(Qt5 REQUIRED Network Widgets ) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED Network Widgets ) +find_package(dtk REQUIRED) +include_directories(${dtk_INCLUDE_DIRS}) ## ############################################################################# ## List Sources @@ -69,15 +70,16 @@ add_library(${TARGET_NAME} SHARED ## ############################################################################# target_link_libraries(${TARGET_NAME} - Qt5::Core - Qt5::Gui - Qt5::Widgets - Qt5::Network + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Network medCore medCoreGui dtkLog - dtkComposer - dtkCore + #dtkComposer + #dtkCore + dtkCoreSupport ) diff --git a/src/plugins/legacy/medShanoir/medShanoirPlugin.h b/src/plugins/legacy/medShanoir/medShanoirPlugin.h index 1797ad1598..6cb9fd7b62 100644 --- a/src/plugins/legacy/medShanoir/medShanoirPlugin.h +++ b/src/plugins/legacy/medShanoir/medShanoirPlugin.h @@ -13,8 +13,10 @@ PURPOSE. =========================================================================*/ #include -#include "medShanoirPluginExport.h" +#include "medShanoirPluginExport.h" +#include +//#include <> class MEDSHANOIRPLUGIN_EXPORT medShanoirPlugin : public medPluginLegacy { Q_OBJECT diff --git a/src/plugins/legacy/medTemporaryDataSource/CMakeLists.txt b/src/plugins/legacy/medTemporaryDataSource/CMakeLists.txt index 24502f67cc..69aecb48bc 100644 --- a/src/plugins/legacy/medTemporaryDataSource/CMakeLists.txt +++ b/src/plugins/legacy/medTemporaryDataSource/CMakeLists.txt @@ -30,7 +30,7 @@ add_definitions(-D${TARGET_NAME_UP}_VERSION="${${TARGET_NAME}_VERSION}") ## ############################################################################# -#find_package(Qt5 REQUIRED Core) +#find_package(Qt${QT_VERSION_MAJOR} REQUIRED Core) #enable_testing(true) #FIND_PACKAGE(GTest REQUIRED) @@ -85,8 +85,8 @@ add_library(${TARGET_NAME} SHARED ## Link ## ############################################################################# target_link_libraries(${TARGET_NAME} PUBLIC - Qt5::Core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets medCore ) @@ -103,13 +103,13 @@ target_link_libraries(${TARGET_NAME} PUBLIC # GTest::gtest # GTest::gmock_main # GTest::gmock -# Qt5::Core +# Qt${QT_VERSION_MAJOR}::Core # medCore # ${TARGET_NAME}) # #project(medTmpDataSourceIntegrationQTest LANGUAGES CXX) # -#find_package(Qt5Test REQUIRED) +#find_package(Qt${QT_VERSION_MAJOR}Test REQUIRED) # ##set(CMAKE_INCLUDE_CURRENT_DIR ON) # @@ -120,7 +120,7 @@ target_link_libraries(${TARGET_NAME} PUBLIC #add_executable(medTmpDataSourceIntegrationQTest ${CMAKE_CURRENT_SOURCE_DIR}/test/medTmpDataSourceIntegrationQTest.cpp) #add_test(NAME medTmpDataSourceIntegrationQTest COMMAND medTmpDataSourceIntegrationQTest) # -#target_link_libraries(medTmpDataSourceIntegrationQTest PRIVATE Qt5::Test Qt5::Sql medCore) +#target_link_libraries(medTmpDataSourceIntegrationQTest PRIVATE Qt${QT_VERSION_MAJOR}::Test Qt${QT_VERSION_MAJOR}::Sql medCore) ## ############################################################################# ## Install rules diff --git a/src/plugins/legacy/medVtkFibersData/interactors/medVtkFibersDataInteractor.cpp b/src/plugins/legacy/medVtkFibersData/interactors/medVtkFibersDataInteractor.cpp index 556b093052..c3363d545b 100644 --- a/src/plugins/legacy/medVtkFibersData/interactors/medVtkFibersDataInteractor.cpp +++ b/src/plugins/legacy/medVtkFibersData/interactors/medVtkFibersDataInteractor.cpp @@ -825,10 +825,10 @@ void medVtkFibersDataInteractor::saveBundlesInDataBase() tmpBundle->setData(bundle); - QString newSeriesDescription = d->data->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->data->fecthMetaData("SeriesDescription"); newSeriesDescription += " "; newSeriesDescription += (*it).first.c_str(); - tmpBundle->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + tmpBundle->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->data->metaDataList() ) { @@ -844,7 +844,7 @@ void medVtkFibersDataInteractor::saveBundlesInDataBase() } QString generatedID = QUuid::createUuid().toString().replace("{","").replace("}",""); - tmpBundle->setMetaData ( medMetaDataKeys::SeriesID.key(), generatedID ); + tmpBundle->setMetaData ( medMetaDataKeys::key("SeriesID"), generatedID ); medDataManager::instance()->importData(tmpBundle); @@ -1545,10 +1545,10 @@ void medVtkFibersDataInteractor::saveCurrentBundle() savedBundle->setData(bundle); - QString newSeriesDescription = d->data->metadata ( medMetaDataKeys::SeriesDescription.key() ); + QString newSeriesDescription = d->data->fecthMetaData("SeriesDescription"); newSeriesDescription += " "; newSeriesDescription += (*it).first.c_str(); - savedBundle->setMetaData ( medMetaDataKeys::SeriesDescription.key(), newSeriesDescription ); + savedBundle->setMetaData ( medMetaDataKeys::key("SeriesDescription"), newSeriesDescription ); for( QString metaData : d->data->metaDataList() ) { @@ -1569,7 +1569,7 @@ void medVtkFibersDataInteractor::saveCurrentBundle() } QString generatedID = QUuid::createUuid().toString().replace("{","").replace("}",""); - savedBundle->setMetaData ( medMetaDataKeys::SeriesID.key(), generatedID ); + savedBundle->setMetaData ( medMetaDataKeys::key("SeriesID"), generatedID ); medDataManager::instance()->importData(savedBundle); } diff --git a/src/plugins/legacy/medVtkView/CMakeLists.txt b/src/plugins/legacy/medVtkView/CMakeLists.txt index 7788ff612e..94bbba40ca 100644 --- a/src/plugins/legacy/medVtkView/CMakeLists.txt +++ b/src/plugins/legacy/medVtkView/CMakeLists.txt @@ -72,10 +72,10 @@ add_library(${TARGET_NAME} SHARED ## ############################################################################# target_link_libraries(${TARGET_NAME} - Qt5::Core - Qt5::Widgets - Qt5::Gui - Qt5::OpenGL + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets + Qt${QT_VERSION_MAJOR}::Gui + Qt${QT_VERSION_MAJOR}::OpenGL dtkCore dtkLog medCore diff --git a/src/plugins/legacy/medVtkView/medVtkView.cpp b/src/plugins/legacy/medVtkView/medVtkView.cpp index 9b0683caab..49ca50448d 100644 --- a/src/plugins/legacy/medVtkView/medVtkView.cpp +++ b/src/plugins/legacy/medVtkView/medVtkView.cpp @@ -443,23 +443,23 @@ void medVtkView::displayDataInfo(uint layer) medAbstractData *data = layerData(layer); if ( data ) { - if ( data->hasMetaData ( medMetaDataKeys::PatientName.key() ) ) + if ( data->hasMetaData ( medMetaDataKeys::key("PatientName") ) ) { - const QString patientName = data->metaDataValues ( medMetaDataKeys::PatientName.key() ) [0]; + const QString patientName = data->metaDataValues ( medMetaDataKeys::key("PatientName") ) [0]; d->view2d->SetPatientName ( patientName.toLatin1().constData() ); d->view3d->SetPatientName ( patientName.toLatin1().constData() ); } - if ( data->hasMetaData ( medMetaDataKeys::StudyDescription.key() ) ) + if ( data->hasMetaData ( medMetaDataKeys::key("StudyDescription") ) ) { - const QString studyName = data->metaDataValues ( medMetaDataKeys::StudyDescription.key() ) [0]; + const QString studyName = data->metaDataValues ( medMetaDataKeys::key("StudyDescription") ) [0]; d->view2d->SetStudyName ( studyName.toLatin1().constData() ); d->view3d->SetStudyName ( studyName.toLatin1().constData() ); } - if ( data->hasMetaData ( medMetaDataKeys::SeriesDescription.key() ) ) + if ( data->hasMetaData ( medMetaDataKeys::key("SeriesDescription") ) ) { - const QString seriesName = data->metaDataValues ( medMetaDataKeys::SeriesDescription.key() ) [0]; + const QString seriesName = data->metaDataValues ( medMetaDataKeys::key("SeriesDescription") ) [0]; d->view2d->SetSeriesName ( seriesName.toLatin1().constData() ); d->view3d->SetSeriesName ( seriesName.toLatin1().constData() ); } diff --git a/src/plugins/legacy/meshManipulation/meshManipulationToolBox.cpp b/src/plugins/legacy/meshManipulation/meshManipulationToolBox.cpp index 4e5f436aaf..d77a8675b5 100644 --- a/src/plugins/legacy/meshManipulation/meshManipulationToolBox.cpp +++ b/src/plugins/legacy/meshManipulation/meshManipulationToolBox.cpp @@ -272,7 +272,7 @@ void meshManipulationToolBox::retrieveRegistrationMatricesFromLayers() QVector matrixAsVector = retrieveMatrixFromArray(array); QString arrayName(array->GetName()); - arrayName += " (" + abstractData->metadata(medMetaDataKeys::SeriesDescription.key()) + ")"; + arrayName += " (" + abstractData->metadata(medMetaDataKeys::key("SeriesDescription")) + ")"; tryAddingRegistrationMatrix(matrixAsVector, arrayName); } } diff --git a/src/plugins/legacy/meshMapping/meshMappingToolBox.cpp b/src/plugins/legacy/meshMapping/meshMappingToolBox.cpp index 1676cee2fa..26fc7156cf 100644 --- a/src/plugins/legacy/meshMapping/meshMappingToolBox.cpp +++ b/src/plugins/legacy/meshMapping/meshMappingToolBox.cpp @@ -169,7 +169,8 @@ void meshMappingToolBox::addLayer(unsigned int layer) { medAbstractData *data = medView->layerData(layer); - QString name = medMetaDataKeys::SeriesDescription.getFirstValue(data,"no name"); + QString name = data->fecthMetaData("SeriesDescription"); + if (name.isEmpty()) name = "no name"; if(data && !data->identifier().contains("vtkDataMesh")) { diff --git a/src/plugins/legacy/polygonRoi/CMakeLists.txt b/src/plugins/legacy/polygonRoi/CMakeLists.txt index faf07c2f22..1ad68f4ed9 100644 --- a/src/plugins/legacy/polygonRoi/CMakeLists.txt +++ b/src/plugins/legacy/polygonRoi/CMakeLists.txt @@ -41,7 +41,7 @@ include(${ITK_USE_FILE}) find_package(VTK REQUIRED COMPONENTS GUISupportQt CommonCore IOLegacy) -find_package(Qt5 REQUIRED COMPONENTS Gui) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui) ## ############################################################################# ## List Sources diff --git a/src/plugins/legacy/polygonRoi/polygonLabel.cpp b/src/plugins/legacy/polygonRoi/polygonLabel.cpp index bcdec2e3eb..76d986d066 100644 --- a/src/plugins/legacy/polygonRoi/polygonLabel.cpp +++ b/src/plugins/legacy/polygonRoi/polygonLabel.cpp @@ -606,7 +606,7 @@ void polygonLabel::createMask(int label, QString &desc, bool originSrc) // output->addParentData(inputData); // QString desc = inputData->getExpectedName() + "_segmented"; // output->setExpectedName(desc); - // output->setMetaData(medMetaDataKeys::SeriesDescription.key(), desc); + // output->setMetaData(medMetaDataKeys::key("SeriesDescription"), desc); //} // medDataManager::instance()->importData(output, originSrc); diff --git a/src/plugins/legacy/polygonRoi/toolboxes/polygonRoiToolBox.cpp b/src/plugins/legacy/polygonRoi/toolboxes/polygonRoiToolBox.cpp index d680fc525c..b81298fe02 100644 --- a/src/plugins/legacy/polygonRoi/toolboxes/polygonRoiToolBox.cpp +++ b/src/plugins/legacy/polygonRoi/toolboxes/polygonRoiToolBox.cpp @@ -274,9 +274,9 @@ void polygonRoiToolBox::onLayerRemoveOnOrientedViews(medAbstractData *data) void polygonRoiToolBox::createAndConnectEventFilter(const medAbstractData *data, medAbstractImageView *imageView) { - QString toolBoxName = data->metaDataValues(medMetaDataKeys::StudyDescription.key())[0] + + QString toolBoxName = data->metaDataValues(medMetaDataKeys::key("StudyDescription"))[0] + " - " + - data->metaDataValues(medMetaDataKeys::SeriesDescription.key())[0]; + data->metaDataValues(medMetaDataKeys::key("SeriesDescription"))[0]; if (specialityPreference==1) { diff --git a/src/plugins/legacy/polygonRoi/viewevent/baseViewEvent.cpp b/src/plugins/legacy/polygonRoi/viewevent/baseViewEvent.cpp index 952ef28f23..801dd2cc93 100644 --- a/src/plugins/legacy/polygonRoi/viewevent/baseViewEvent.cpp +++ b/src/plugins/legacy/polygonRoi/viewevent/baseViewEvent.cpp @@ -774,7 +774,7 @@ void baseViewEvent::saveAllContours() description = QString("%1 contours").arg(contoursData.size()); } medAbstractData * data = currentView->layerData(0); - description += " (" + data->metadata(medMetaDataKeys::SeriesDescription.key()) + ")"; + description += " (" + data->fecthMetaData("SeriesDescription") + ")"; medUtilities::setDerivedMetaData(contourOutput, data, description, false, false); contourOutput->setData(outputDataSet); @@ -960,7 +960,7 @@ QString baseViewEvent::createMaskDescription(polygonLabel *label) { QString name = QString(label->getName()); medAbstractData * data = currentView->layerData(0); - QString desc = QString("mask ") + name + " (" + data->metadata(medMetaDataKeys::SeriesDescription.key()) + ")"; + QString desc = QString("mask ") + name + " (" + data->fecthMetaData("SeriesDescription") + ")"; return desc; } @@ -1009,7 +1009,7 @@ void baseViewEvent::saveContour(polygonLabel *label) description = QString("%1 contours ").arg(contoursData.size()); } medAbstractData * data = currentView->layerData(0); - description += " (" + data->metadata(medMetaDataKeys::SeriesDescription.key()) + ")"; + description += " (" + data->fecthMetaData("SeriesDescription") + ")"; medUtilities::setDerivedMetaData(contourOutput, data, description, false, false); diff --git a/src/plugins/legacy/polygonRoi/viewevent/urologyViewEvent.cpp b/src/plugins/legacy/polygonRoi/viewevent/urologyViewEvent.cpp index 627a84549f..188f9fae72 100644 --- a/src/plugins/legacy/polygonRoi/viewevent/urologyViewEvent.cpp +++ b/src/plugins/legacy/polygonRoi/viewevent/urologyViewEvent.cpp @@ -238,8 +238,8 @@ QString urologyViewEvent::createMaskDescription(polygonLabel *label) { QString name = (label->getOptName() == QString()) ? QString(label->getName()) : QString("%1_%2").arg(label->getName()).arg(label->getOptName()); medAbstractData * data = currentView->layerData(0); - QString seriesDesc = data->metadata(medMetaDataKeys::SeriesDescription.key()); - QString patientName = data->metadata(medMetaDataKeys::PatientName.key()); + QString seriesDesc = data->fecthMetaData("SeriesDescription"); + QString patientName = data->fecthMetaData("PatientName"); if (seriesDesc.contains("T2")) { seriesDesc = "T2"; diff --git a/src/plugins/legacy/reformat/CMakeLists.txt b/src/plugins/legacy/reformat/CMakeLists.txt index 51e3fc1adc..6a52c4eb99 100644 --- a/src/plugins/legacy/reformat/CMakeLists.txt +++ b/src/plugins/legacy/reformat/CMakeLists.txt @@ -74,7 +74,7 @@ add_library(${TARGET_NAME} SHARED target_link_libraries(${TARGET_NAME} PRIVATE ${QT_LIBRARIES} - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core ITKCommon ITKTransform medCore diff --git a/src/plugins/legacy/undoRedoRegistration/CMakeLists.txt b/src/plugins/legacy/undoRedoRegistration/CMakeLists.txt index 939c9c711e..b114266603 100644 --- a/src/plugins/legacy/undoRedoRegistration/CMakeLists.txt +++ b/src/plugins/legacy/undoRedoRegistration/CMakeLists.txt @@ -76,8 +76,8 @@ add_library(${TARGET_NAME} SHARED ## ############################################################################# target_link_libraries(${TARGET_NAME} - Qt5::Core - Qt5::Widgets + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Widgets dtkLog dtkCore medCore diff --git a/src/plugins/legacy/vtkDataMesh/readers/vtkDataMeshReader.cpp b/src/plugins/legacy/vtkDataMesh/readers/vtkDataMeshReader.cpp index 41d0d85dcd..68200451b0 100644 --- a/src/plugins/legacy/vtkDataMesh/readers/vtkDataMeshReader.cpp +++ b/src/plugins/legacy/vtkDataMesh/readers/vtkDataMeshReader.cpp @@ -105,10 +105,10 @@ bool vtkDataMeshReader::read(const QString& path) } // Use filename as series description if no meta data could be found - if (medData->metadata(medMetaDataKeys::SeriesDescription.key()).isEmpty()) + if (medData->fecthMetaData("SeriesDescription").isEmpty()) { QFileInfo file(path); - medData->setMetaData(medMetaDataKeys::SeriesDescription.key(), file.baseName()); + medData->setMetaData(medMetaDataKeys::key("SeriesDescription"), file.baseName()); } setProgress(100); @@ -159,8 +159,8 @@ bool vtkDataMeshReader::extractCartoMetaData(vtkMetaDataSet* dataSet) if (dataSet->GetMetaData("PatientName", patientName) && dataSet->GetMetaData("PatientID", patientID)) { - data()->setMetaData(medMetaDataKeys::PatientName.key(), QString::fromStdString(patientName)); - data()->setMetaData(medMetaDataKeys::PatientID.key(), QString::fromStdString(patientID)); + data()->setMetaData(medMetaDataKeys::key("PatientName"), QString::fromStdString(patientName)); + data()->setMetaData(medMetaDataKeys::key("PatientID"), QString::fromStdString(patientID)); result = true; } diff --git a/src/plugins/medITKImageDTKImageConverter/CMakeLists.txt b/src/plugins/medITKImageDTKImageConverter/CMakeLists.txt index 46153c2b3c..446750ad6b 100644 --- a/src/plugins/medITKImageDTKImageConverter/CMakeLists.txt +++ b/src/plugins/medITKImageDTKImageConverter/CMakeLists.txt @@ -63,7 +63,7 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} ITKCommon - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkLog medCore diff --git a/src/plugins/medImagingCompatibility/CMakeLists.txt b/src/plugins/medImagingCompatibility/CMakeLists.txt index 8e02902741..a4c3f33f52 100644 --- a/src/plugins/medImagingCompatibility/CMakeLists.txt +++ b/src/plugins/medImagingCompatibility/CMakeLists.txt @@ -61,8 +61,8 @@ target_include_directories(${TARGET_NAME} ## ############################################################################# target_link_libraries(${TARGET_NAME} - Qt5::Core - Qt5::Gui + Qt${QT_VERSION_MAJOR}::Core + Qt${QT_VERSION_MAJOR}::Gui medCore dtkLog dtkComposer diff --git a/src/plugins/process/arithmetic_operation/CMakeLists.txt b/src/plugins/process/arithmetic_operation/CMakeLists.txt index 2dc684dd24..079f5dd6f4 100644 --- a/src/plugins/process/arithmetic_operation/CMakeLists.txt +++ b/src/plugins/process/arithmetic_operation/CMakeLists.txt @@ -64,7 +64,7 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} ITKCommon - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkLog medCore diff --git a/src/plugins/process/bias_correction/CMakeLists.txt b/src/plugins/process/bias_correction/CMakeLists.txt index 0c080e8823..258343260a 100644 --- a/src/plugins/process/bias_correction/CMakeLists.txt +++ b/src/plugins/process/bias_correction/CMakeLists.txt @@ -65,7 +65,7 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} ITKCommon ITKStatistics - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkLog medCore diff --git a/src/plugins/process/dwi_basic_thresholding/CMakeLists.txt b/src/plugins/process/dwi_basic_thresholding/CMakeLists.txt index 8990fcf9d5..a8872d43c4 100644 --- a/src/plugins/process/dwi_basic_thresholding/CMakeLists.txt +++ b/src/plugins/process/dwi_basic_thresholding/CMakeLists.txt @@ -61,7 +61,7 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} ITKCommon - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkLog medCore diff --git a/src/plugins/process/itkDWIBrainMaskCalculatorProcess/CMakeLists.txt b/src/plugins/process/itkDWIBrainMaskCalculatorProcess/CMakeLists.txt index e2efb091c5..8a752e89ee 100644 --- a/src/plugins/process/itkDWIBrainMaskCalculatorProcess/CMakeLists.txt +++ b/src/plugins/process/itkDWIBrainMaskCalculatorProcess/CMakeLists.txt @@ -67,7 +67,7 @@ target_link_libraries(${TARGET_NAME} ITKSmoothing TTK::Registration TTK::ttkAlgorithms - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkCoreSupport dtkLog diff --git a/src/plugins/process/mask_image/CMakeLists.txt b/src/plugins/process/mask_image/CMakeLists.txt index e5734b073c..2b44970fb5 100644 --- a/src/plugins/process/mask_image/CMakeLists.txt +++ b/src/plugins/process/mask_image/CMakeLists.txt @@ -64,7 +64,7 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} ITKCommon - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkLog medCore diff --git a/src/plugins/process/morphomath_operation/CMakeLists.txt b/src/plugins/process/morphomath_operation/CMakeLists.txt index 388d78a33e..2f945ed6f0 100644 --- a/src/plugins/process/morphomath_operation/CMakeLists.txt +++ b/src/plugins/process/morphomath_operation/CMakeLists.txt @@ -64,7 +64,7 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} ITKMathematicalMorphology - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkLog medCore diff --git a/src/plugins/process/single_filter/CMakeLists.txt b/src/plugins/process/single_filter/CMakeLists.txt index 673cd347f9..b24eb18035 100644 --- a/src/plugins/process/single_filter/CMakeLists.txt +++ b/src/plugins/process/single_filter/CMakeLists.txt @@ -65,7 +65,7 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} ITKCommon ITKSmoothing - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkLog medCore diff --git a/src/plugins/process/ttkTensorEstimationProcess/CMakeLists.txt b/src/plugins/process/ttkTensorEstimationProcess/CMakeLists.txt index 7c46bffbac..9624470a83 100644 --- a/src/plugins/process/ttkTensorEstimationProcess/CMakeLists.txt +++ b/src/plugins/process/ttkTensorEstimationProcess/CMakeLists.txt @@ -48,7 +48,7 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} ITKCommon - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkCoreSupport dtkLog diff --git a/src/plugins/process/ttkTensorScalarMapsProcess/CMakeLists.txt b/src/plugins/process/ttkTensorScalarMapsProcess/CMakeLists.txt index 9672aa8fe5..a68ec0ffa1 100644 --- a/src/plugins/process/ttkTensorScalarMapsProcess/CMakeLists.txt +++ b/src/plugins/process/ttkTensorScalarMapsProcess/CMakeLists.txt @@ -50,7 +50,7 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} ITKCommon - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkCoreSupport dtkLog diff --git a/src/plugins/process/ttkTensorScalarMapsProcess/ttkTensorScalarMapsProcess.cpp b/src/plugins/process/ttkTensorScalarMapsProcess/ttkTensorScalarMapsProcess.cpp index 6338da3a70..12b31156f6 100644 --- a/src/plugins/process/ttkTensorScalarMapsProcess/ttkTensorScalarMapsProcess.cpp +++ b/src/plugins/process/ttkTensorScalarMapsProcess/ttkTensorScalarMapsProcess.cpp @@ -123,7 +123,7 @@ medAbstractJob::medJobExitStatus ttkTensorScalarMapsProcess::_run() return medAbstractJob::MED_JOB_EXIT_CANCELLED; } - output->setMetaData(medMetaDataKeys::SeriesDescription.key(), this->input()->metadata(medMetaDataKeys::SeriesDescription.key()) + " " + m_scalarMapRequested); + output->setMetaData(medMetaDataKeys::key("SeriesDescription"), this->input()->fecthMetaData("SeriesDescription") + " " + m_scalarMapRequested); this->setOutput(output); return medAbstractJob::MED_JOB_EXIT_SUCCESS; } @@ -184,7 +184,7 @@ medAbstractJob::medJobExitStatus ttkTensorScalarMapsProcess::_run() output = qobject_cast (medAbstractDataFactory::instance()->create ("itkDataImageFloat3")); output->setData(filter->GetOutput()); - output->setMetaData(medMetaDataKeys::SeriesDescription.key(), this->input()->metadata(medMetaDataKeys::SeriesDescription.key()) + " " + m_scalarMapRequested); + output->setMetaData(medMetaDataKeys::key("SeriesDescription"), this->input()->fecthMetaData("SeriesDescription") + " " + m_scalarMapRequested); this->setOutput(output); diff --git a/src/plugins/process/ttkTensorTractographyProcess/CMakeLists.txt b/src/plugins/process/ttkTensorTractographyProcess/CMakeLists.txt index 024eabb1aa..bb467561fc 100644 --- a/src/plugins/process/ttkTensorTractographyProcess/CMakeLists.txt +++ b/src/plugins/process/ttkTensorTractographyProcess/CMakeLists.txt @@ -71,7 +71,7 @@ target_include_directories(${TARGET_NAME} target_link_libraries(${TARGET_NAME} ITKCommon - Qt5::Core + Qt${QT_VERSION_MAJOR}::Core dtkCore dtkCoreSupport dtkLog diff --git a/superbuild/CMakeLists.txt b/superbuild/CMakeLists.txt index d5a08d4140..d2be24f338 100644 --- a/superbuild/CMakeLists.txt +++ b/superbuild/CMakeLists.txt @@ -15,7 +15,7 @@ ## Add packages ## ############################################################################# -find_package(Qt5 REQUIRED COMPONENTS +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Designer Gui @@ -28,8 +28,6 @@ find_package(Qt5 REQUIRED COMPONENTS Quick ) -find_package(Boost REQUIRED) - ## ############################################################################# ## Add exteral projects ## ############################################################################# @@ -43,9 +41,13 @@ find_package(Boost REQUIRED) # * otherwise use download and compile locally the package as an external # module. -option(USE_DTKIMAGING "Use DTK imaging layer" OFF ) - +option(USE_DTKIMAGING "Use DTK imaging layer" OFF ) option(USE_OSPRay "Use OSPRay for CPU VR" OFF ) +option(USE_LASTEST_ITK "Try to use the lastest ..ITK on master branch" OFF) +option(USE_LASTEST_VTK "Try to use the lastest ..VTK on master branch" OFF) +option(USE_LASTEST_TTK "Try to use the lastest ..TTK on master branch" OFF) +option(USE_LASTEST_RPI "Try to use the lastest ..RPI on master branch" OFF) +option(USE_LASTEST_DCMTK "Try to use the lastest DCMTK on master branch" OFF) if (NOT WIN32) option(USE_FFmpeg "Build with FFmpeg video export support" OFF) @@ -140,7 +142,7 @@ file(APPEND ${${PROJECT_NAME}_CONFIG_FILE} # Add Qt dir file(APPEND ${${PROJECT_NAME}_CONFIG_FILE} - "set(Qt5_DIR ${Qt5_DIR})\n\n" + "set(Qt${QT_VERSION_MAJOR}_DIR ${Qt${QT_VERSION_MAJOR}_DIR})\n\n" ) set(CMAKE_MODULE_PATH diff --git a/superbuild/projects_modules/DCMTK.cmake b/superbuild/projects_modules/DCMTK.cmake index fadb984956..5102d3b3d9 100644 --- a/superbuild/projects_modules/DCMTK.cmake +++ b/superbuild/projects_modules/DCMTK.cmake @@ -39,8 +39,14 @@ if (NOT USE_SYSTEM_${ep}) ## Set up versioning control ## ############################################################################# -set(git_url ${GITHUB_PREFIX}DCMTK/dcmtk.git) -set(git_tag DCMTK-3.6.7) +set(git_url git@github.com:DCMTK/dcmtk.git) +if(${USE_LASTEST_DCMTK}) + set(git_tag master) +else() + set(git_tag DCMTK-3.6.7) +endif() + + ## ############################################################################# ## Check if patch has to be applied diff --git a/superbuild/projects_modules/ITK.cmake b/superbuild/projects_modules/ITK.cmake index 3ec43f10d7..ba4cc67a8f 100644 --- a/superbuild/projects_modules/ITK.cmake +++ b/superbuild/projects_modules/ITK.cmake @@ -40,7 +40,11 @@ if (NOT USE_SYSTEM_${ep}) set(git_url ${GITHUB_PREFIX}InsightSoftwareConsortium/ITK.git) -set(git_tag v5.4rc04) +if(${USE_LASTEST_ITK}) + set(git_tag master) +else() + set(git_tag v5.4rc04) +endif() ## ############################################################################# @@ -74,6 +78,12 @@ set(cmake_cache_args -DCMAKE_INSTALL_PREFIX:PATH=${EP_INSTALL_PREFIX}/${ep} ) +## ############################################################################# +## Check if patch has to be applied +## ############################################################################# + +# ep_GeneratePatchCommand(${ep} ${ep}_PATCH_COMMAND ITK.patch) + ## ############################################################################# ## Add external-project ## ############################################################################# diff --git a/superbuild/projects_modules/RPI.cmake b/superbuild/projects_modules/RPI.cmake index 0965699f83..0fb23870cf 100644 --- a/superbuild/projects_modules/RPI.cmake +++ b/superbuild/projects_modules/RPI.cmake @@ -41,7 +41,11 @@ if (NOT USE_SYSTEM_${ep}) ## ############################################################################# set(git_url ${GITHUB_PREFIX}medInria/RPI.git) -set(git_tag RPI_INTERFACE) +if(${USE_LASTEST_RPI}) + set(git_tag master) +else() + set(git_tag RPI_INTERFACE) +endif() ## ############################################################################# ## Add specific cmake arguments for configuration step of the project diff --git a/superbuild/projects_modules/TTK.cmake b/superbuild/projects_modules/TTK.cmake index eef986f1ef..9ccf72c1be 100644 --- a/superbuild/projects_modules/TTK.cmake +++ b/superbuild/projects_modules/TTK.cmake @@ -40,7 +40,12 @@ if (NOT USE_SYSTEM_${ep}) ## ############################################################################# set(git_url ${GITHUB_PREFIX}medInria/TTK.git) -set(git_tag ITK5.4rc04+VTK9) +if(${USE_LASTEST_TTK}) + set(git_tag master) +else() + set(git_tag ITK5.4rc04+VTK9) + #set(git_tag ModernCMake) +endif() ## ############################################################################# ## Add specific cmake arguments for configuration step of the project diff --git a/superbuild/projects_modules/VTK.cmake b/superbuild/projects_modules/VTK.cmake index 7b14537078..7ba6212603 100644 --- a/superbuild/projects_modules/VTK.cmake +++ b/superbuild/projects_modules/VTK.cmake @@ -39,7 +39,12 @@ if (NOT USE_SYSTEM_${ep}) ## ############################################################################# set(git_url ${GITHUB_PREFIX}Kitware/VTK.git) -set(git_tag v9.2.6) +if(${USE_LASTEST_VTK}) + set(git_tag master) +else() + #set(git_tag v8.1.2) + set(git_tag v9.2.6) +endif() ## ############################################################################# ## Add specific cmake arguments for configuration step of the project @@ -77,7 +82,7 @@ set(cmake_args ) set(cmake_cache_args - -DQt5_DIR:FILEPATH=${Qt5_DIR} + -DQt${QT_VERSION_MAJOR}_DIR:FILEPATH=${Qt${QT_VERSION_MAJOR}_DIR} -DCMAKE_INSTALL_PREFIX:PATH=${EP_INSTALL_PREFIX}/${ep} -DCOMPILER_HAS_HIDDEN_VISIBILITY:INTERNAL=ON ) @@ -114,6 +119,12 @@ if(${USE_FFmpeg}) ) endif() +## ############################################################################# +## Check if patch has to be applied +## ############################################################################# + +# ep_GeneratePatchCommand(${ep} ${ep}_PATCH_COMMAND VTK.patch) + ## ############################################################################# ## Add external-project ## ############################################################################# @@ -139,6 +150,7 @@ ExternalProject_Add(${ep} BUILD_ALWAYS ${EP_BUILD_ALWAYS} ${EP_INSTAL_COMMAND} ) + ## ############################################################################# ## Set variable to provide infos about the project ## ############################################################################# diff --git a/superbuild/projects_modules/dtk.cmake b/superbuild/projects_modules/dtk.cmake index fe8e89c468..9581ed1486 100644 --- a/superbuild/projects_modules/dtk.cmake +++ b/superbuild/projects_modules/dtk.cmake @@ -66,7 +66,7 @@ set(cmake_args -DCMAKE_CXX_FLAGS:STRING=${${ep}_cxx_flags} -DCMAKE_SHARED_LINKER_FLAGS:STRING=${${ep}_shared_linker_flags} -DBUILD_SHARED_LIBS:BOOL=${BUILD_SHARED_LIBS_${ep}} - -DDTK_BUILD_COMPOSER=ON + -DDTK_BUILD_COMPOSER=OFF -DDTK_BUILD_DISTRIBUTED=ON -DDTK_BUILD_SCRIPT=OFF -DDTK_BUILD_SUPPORT_COMPOSER=OFF @@ -81,7 +81,7 @@ set(cmake_args ) set(cmake_cache_args - -DQt5_DIR:FILEPATH=${Qt5_DIR} + -DQt${QT_VERSION_MAJOR}_DIR:FILEPATH=${Qt${QT_VERSION_MAJOR}_DIR} -DCMAKE_INSTALL_PREFIX:PATH=${EP_INSTALL_PREFIX}/${ep} ) diff --git a/superbuild/projects_modules/dtkImaging.cmake b/superbuild/projects_modules/dtkImaging.cmake index 0218c309f2..85d42662b4 100644 --- a/superbuild/projects_modules/dtkImaging.cmake +++ b/superbuild/projects_modules/dtkImaging.cmake @@ -69,7 +69,7 @@ set(cmake_args ) set(cmake_cache_args - -DQt5_DIR=${Qt5_DIR} + -DQt${QT_VERSION_MAJOR}_DIR=${Qt${QT_VERSION_MAJOR}_DIR} ) diff --git a/superbuild/projects_modules/medInria.cmake b/superbuild/projects_modules/medInria.cmake index 6f3043471c..f85b784062 100644 --- a/superbuild/projects_modules/medInria.cmake +++ b/superbuild/projects_modules/medInria.cmake @@ -64,6 +64,12 @@ if(CMAKE_COMPILER_IS_GNUCXX) set(${ep}_cxx_flags "${${ep}_cxx_flags} -fpermissive") endif() +if(${SDK_GENERATION}) + set(MEDINRIA_INSTALL_PREFIX ${SDK_DIR}) +else() + set(MEDINRIA_INSTALL_PREFIX "") +endif() + set(cmake_args ${ep_common_cache_args} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE_medInria} @@ -87,7 +93,8 @@ set(cmake_cache_args -DTTK_ROOT:PATH=${TTK_ROOT} -DVTK_ROOT:PATH=${VTK_ROOT} #-DGTest_ROOT:PATH=${GTEST_ROOT} - -DQt5_ROOT:PATH=${Qt5_ROOT} + -DQt${QT_VERSION_MAJOR}_ROOT:PATH=${Qt${QT_VERSION_MAJOR}_ROOT} + -DDCMTK_DIR:PATH=${DCMTK_DIR} -Ddtk_DIR:PATH=${dtk_DIR} @@ -95,13 +102,9 @@ set(cmake_cache_args -DRPI_DIR:PATH=${RPI_DIR} -DTTK_DIR:PATH=${TTK_DIR} -DVTK_DIR:PATH=${VTK_DIR} - #-DGTest_DIR:PATH=${GTEST_DIR} - -DQt5_DIR:PATH=${Qt5_DIR} - - -DBoost_INCLUDE_DIR:PATH=${Boost_INCLUDE_DIR} - -DCMAKE_INSTALL_PREFIX:PATH=${SDK_DIR} - #-DSDK_GENERATION:BOOL=${SDK_GENERATION} - #-DSDK_PACKAGING:BOOL=${SDK_PACKAGING} + -DCMAKE_INSTALL_PREFIX:PATH=${MEDINRIA_INSTALL_PREFIX} + -DQt${QT_VERSION_MAJOR}_DIR:PATH=${Qt${QT_VERSION_MAJOR}_DIR} + -DCMAKE_BUILD_PARALLEL_LEVEL:STRING=8 ) if (${USE_FFmpeg}) @@ -124,7 +127,7 @@ ExternalProject_Add(${ep} SOURCE_DIR ${medInria_SOURCE_DIR} BINARY_DIR ${medInria_BINARY_DIR} STAMP_DIR ${medinria_Stamp_DIR} - INSTALL_DIR ${SDK_DIR} + INSTALL_DIR ${MEDINRIA_INSTALL_PREFIX} UPDATE_COMMAND "" CMAKE_GENERATOR ${gen} @@ -146,15 +149,28 @@ set(${ep}_DIR ${binary_dir} PARENT_SCOPE) ExternalProject_Get_Property(${ep} source_dir) set(${ep}_SOURCE_DIR ${source_dir} PARENT_SCOPE) - - + +find_package(Qt5 REQUIRED Core) + +function(dump_cmake_variables) + get_cmake_property(_variableNames VARIABLES) + list (SORT _variableNames) + foreach (_variableName ${_variableNames}) + if ((NOT DEFINED ARGV0) OR _variableName MATCHES ${ARGV0}) + message(STATUS "${_variableName}=${${_variableName}}") + endif() + endforeach() +endfunction() + + if (WIN32) - file(TO_NATIVE_PATH ${ITK_ROOT} ITK_BIN_BASE) - file(TO_NATIVE_PATH ${VTK_ROOT} VTK_BIN_BASE) - file(TO_NATIVE_PATH ${TTK_ROOT} TTK_BIN_BASE) - file(TO_NATIVE_PATH ${dtk_ROOT} DTK_BIN_BASE) - file(TO_NATIVE_PATH ${_qt5Core_install_prefix} QT5_BIN_BASE) - file(TO_NATIVE_PATH ${medInria_BINARY_DIR} MED_BIN_BASE) + file(TO_NATIVE_PATH ${ITK_ROOT} ITK_BIN_BASE) + file(TO_NATIVE_PATH ${VTK_ROOT} VTK_BIN_BASE) + file(TO_NATIVE_PATH ${TTK_ROOT} TTK_BIN_BASE) + file(TO_NATIVE_PATH ${dtk_ROOT} DTK_BIN_BASE) + file(TO_NATIVE_PATH ${Qt${QT_VERSION_MAJOR}_DIR}/../../.. QTX_BIN_BASE) + file(TO_NATIVE_PATH ${medInria_BINARY_DIR} MED_BIN_BASE) + set(CONFIG_MODE $<$:Debug>$<$:Release>$<$:MinSizeRel>$<$:RelWithDebInfo>) @@ -166,8 +182,7 @@ if (WIN32) COMMAND for %%I in ( ${VTK_BIN_BASE}\\bin\\${CONFIG_MODE}\\*.dll ) do (if EXIST ${MED_BIN_BASE}\\%%~nxI (del /S ${MED_BIN_BASE}\\%%~nxI & mklink /H ${MED_BIN_BASE}\\%%~nxI %%~fI) else mklink /H ${MED_BIN_BASE}\\%%~nxI %%~fI) COMMAND for %%I in ( ${DTK_BIN_BASE}\\bin\\${CONFIG_MODE}\\*.dll ) do (if EXIST ${MED_BIN_BASE}\\%%~nxI (del /S ${MED_BIN_BASE}\\%%~nxI & mklink /H ${MED_BIN_BASE}\\%%~nxI %%~fI) else mklink /H ${MED_BIN_BASE}\\%%~nxI %%~fI) COMMAND for %%I in ( ${TTK_BIN_BASE}\\bin\\*.dll ) do (if EXIST ${MED_BIN_BASE}\\%%~nxI (del /S ${MED_BIN_BASE}\\%%~nxI & mklink /H ${MED_BIN_BASE}\\%%~nxI %%~fI) else mklink /H ${MED_BIN_BASE}\\%%~nxI %%~fI) - COMMAND for %%I in ( ${QT5_BIN_BASE}\\bin\\*.dll ) do (if EXIST ${MED_BIN_BASE}\\%%~nxI (del /S ${MED_BIN_BASE}\\%%~nxI & mklink /H ${MED_BIN_BASE}\\%%~nxI %%~fI) else mklink /H ${MED_BIN_BASE}\\%%~nxI %%~fI) - #COMMAND ${CMAKE_COMMAND} -E copy ${medInria_SOURCE_DIR}/cmake/dtkConfig.cmake.in ${EP_INSTALL_PREFIX}/dtk/lib/cmake/dtk/dtkConfig.cmake + COMMAND for %%I in ( ${QTX_BIN_BASE}\\bin\\*.dll ) do (if EXIST ${MED_BIN_BASE}\\%%~nxI (del /S ${MED_BIN_BASE}\\%%~nxI & mklink /H ${MED_BIN_BASE}\\%%~nxI %%~fI) else mklink /H ${MED_BIN_BASE}\\%%~nxI %%~fI) ) endif()