Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENH: Make DICOM database relocatable #946

Merged
merged 1 commit into from
Jan 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Libs/Core/ctkCorePythonQtDecorators.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

// CTK includes
#include <ctkBooleanMapper.h>
#include <ctkUtils.h>
#include <ctkErrorLogContext.h>
#include <ctkWorkflowStep.h>
#include <ctkWorkflowTransitions.h>
Expand Down Expand Up @@ -234,10 +235,32 @@ public Q_SLOTS:

};

//-----------------------------------------------------------------------------
class PythonQtWrapper_CTKCore : public QObject
{
Q_OBJECT

public Q_SLOTS:
QString static_ctkCoreUtils_absolutePathFromInternal(const QString& internalPath, const QString& basePath)
{
return ctk::absolutePathFromInternal(internalPath, basePath);
}

QString static_ctkCoreUtils_internalPathFromAbsolute(const QString& absolutePath, const QString& basePath)
{
return ctk::internalPathFromAbsolute(absolutePath, basePath);
}
};

//-----------------------------------------------------------------------------
void initCTKCorePythonQtDecorators()
{
PythonQt::self()->addDecorators(new ctkCorePythonQtDecorators);

// PythonQt doesn't support wrapping a static function and adding it to the top-level
// ctk module. This exposes static functions from ctkCoreUtils as ctk.ctkCoreUtils.absolutePathFromInternal(), etc.
// Note that PythonQtWrapper_CTKCore installs itself as ctk.ctk but using that same module here would replace PythonQtWrapper_CTKCore.
PythonQt::self()->registerCPPClass("ctkCoreUtils", "", "CTKCore", PythonQtCreateObject<PythonQtWrapper_CTKCore>);
}

#endif
50 changes: 50 additions & 0 deletions Libs/Core/ctkUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,3 +413,53 @@ qint64 ctk::msecsTo(const QDateTime& t1, const QDateTime& t2)
return static_cast<qint64>(utcT1.daysTo(utcT2)) * static_cast<qint64>(1000*3600*24)
+ static_cast<qint64>(utcT1.time().msecsTo(utcT2.time()));
}

//------------------------------------------------------------------------------
QString ctk::absolutePathFromInternal(const QString& internalPath, const QString& basePath)
{
if (internalPath.isEmpty())
{
return internalPath;
}
if (QFileInfo(internalPath).isRelative())
{
QDir baseDirectory(basePath);
return QDir::cleanPath(baseDirectory.filePath(internalPath));
}
else
{
return internalPath;
}
}

//------------------------------------------------------------------------------
QString ctk::internalPathFromAbsolute(const QString& absolutePath, const QString& basePath)
{
if (absolutePath.isEmpty())
{
return absolutePath;
}
// Make it a relative path if it is within the base folder
if (QFileInfo(absolutePath).isRelative())
{
// already relative path, return it as is
return absolutePath;
}
QString baseFolderClean = QDir::cleanPath(QDir::fromNativeSeparators(basePath));
QString absolutePathClean = QDir::cleanPath(QDir::fromNativeSeparators(absolutePath));
#ifdef Q_OS_WIN32
Qt::CaseSensitivity sensitivity = Qt::CaseInsensitive;
#else
Qt::CaseSensitivity sensitivity = Qt::CaseSensitive;
#endif
if (absolutePathClean.startsWith(baseFolderClean, sensitivity))
{
// file is in the base folder, make it a relative path
// (remove size+1 to remove the leading forward slash)
return absolutePathClean.remove(0, baseFolderClean.size() + 1);
}
else
{
return absolutePath;
}
}
11 changes: 11 additions & 0 deletions Libs/Core/ctkUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,17 @@ QString CTK_CORE_EXPORT qtHandleToString(Qt::HANDLE handle);
/// bumping the minimum required Qt version for CTK.
qint64 CTK_CORE_EXPORT msecsTo(const QDateTime& t1, const QDateTime& t2);

/// Get absolute path from an "internal" path. If internal path is already an absolute path
/// then that is returned unchanged. If internal path is relative path then basePath is used
/// as a basis (prepended to internalPath).
QString CTK_CORE_EXPORT absolutePathFromInternal(const QString& internalPath, const QString& basePath);

/// Get "internal" path from an absolute path. internalPath will be a relative path if
/// absolutePath is within the basePath, otherwise interalPath will be the same as absolutePath.
/// This is useful for paths/directories relative to a base folder, to make the data or application relocatable.
/// Absolute path can be retrieved from an internal path using absolutePathFromInternal function.
QString CTK_CORE_EXPORT internalPathFromAbsolute(const QString& absolutePath, const QString& basePath);

}

#endif
Loading