Skip to content

Commit

Permalink
ENH: adds hook for loading directory archetypes
Browse files Browse the repository at this point in the history
When a directory is added via the Add Data dialog,
it may contain a collection of files that should be
treated as a single MRML data type, such as a series
of image files that get loaded as a volume.

This change allows a qSlicerFileReader subclass to define
a method that can examine the contents of a directory and
filter out any files that should be loaded as a group.  One
of these files then serves as the archetype and the io properties
can be configured such that the files are loaded correctly.
  • Loading branch information
pieper committed Feb 8, 2019
1 parent 7c5c6ee commit 81b744b
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 1 deletion.
15 changes: 15 additions & 0 deletions Base/QTCore/qSlicerCoreIOManager.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -781,3 +781,18 @@ void qSlicerCoreIOManager::setDefaultSceneFileType(QString fileType)
Q_D(qSlicerCoreIOManager);
d->DefaultSceneFileType = fileType;
}

//-----------------------------------------------------------------------------
bool qSlicerCoreIOManager::examineFileInfoList(QFileInfoList &fileInfoList, QFileInfo &archetypeFileInfo, qSlicerIO::IOProperties &ioProperties)const
{
Q_D(const qSlicerCoreIOManager);
QList<qSlicerFileReader*> res;
foreach(qSlicerFileReader* reader, d->Readers)
{
if (reader->examineFileInfoList(fileInfoList, archetypeFileInfo, ioProperties))
{
return (true);
}
}
return (false);
}
18 changes: 17 additions & 1 deletion Base/QTCore/qSlicerCoreIOManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@
#define __qSlicerCoreIOManager_h

// Qt includes
#include <QList>
#include <QFileInfo>
#include <QImage>
#include <QList>
#include <QMap>
#include <QObject>
#include <QVariantMap>
Expand Down Expand Up @@ -170,6 +171,21 @@ class Q_SLICER_BASE_QTCORE_EXPORT qSlicerCoreIOManager:public QObject
/// Defines the file format that should be offered by default when the scene is saved.
Q_INVOKABLE QString defaultSceneFileType()const;

/// Iterates through readers looking at the fileInfoList to see if there is an entry that can serve as
/// an archetype for loading multiple fileInfos. If so, the reader removes the recognized
/// fileInfos from the list and sets the ioProperties so that the corresponding
/// loader will read these files. The archetypeEntry will contain the fileInfo
/// for the archetype and the method returns true. If no pattern is recognized
/// the method returns false.
/// The specific motivating use case is when the file
/// list contains a set of related files, such as a list of image files that
/// are recognized as a volume. But other cases could also make sense, such as when
/// a file format has a set or related files such as textures or material files
/// for a surface model.
/// \sa qSlicerDataDialog
/// \sa qSlicerFileReader
Q_INVOKABLE bool examineFileInfoList(QFileInfoList &fileInfoList, QFileInfo &archetypeEntry, qSlicerIO::IOProperties &ioProperties)const;

public slots:

/// Defines the file format that should be offered by default when the scene is saved.
Expand Down
6 changes: 6 additions & 0 deletions Base/QTCore/qSlicerFileReader.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,9 @@ QStringList qSlicerFileReader::loadedNodes()const
Q_D(const qSlicerFileReader);
return d->LoadedNodes;
}

//----------------------------------------------------------------------------
bool qSlicerFileReader::examineFileInfoList(QFileInfoList &fileInfoList, QFileInfo archetypeEntry, qSlicerIO::IOProperties &ioProperties)const
{
return(false);
}
8 changes: 8 additions & 0 deletions Base/QTCore/qSlicerFileReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#ifndef __qSlicerFileReader_h
#define __qSlicerFileReader_h

// Qt includes
#include <QFileInfo>

// QtCore includes
#include "qSlicerIO.h"
#include "qSlicerBaseQTCoreExport.h"
Expand Down Expand Up @@ -64,6 +67,11 @@ class Q_SLICER_BASE_QTCORE_EXPORT qSlicerFileReader
/// \sa setLoadedNodes(), load()
QStringList loadedNodes()const;

/// Implements the file list examination for the corresponding method in the core
/// IO manager.
/// \sa qSlicerCoreIOManager
virtual bool examineFileInfoList(QFileInfoList &fileInfoList, QFileInfo archetypeEntry, qSlicerIO::IOProperties &ioProperties)const;

protected:
/// Must be called in load() on success with the list of nodes added into the
/// scene.
Expand Down
32 changes: 32 additions & 0 deletions Base/QTGUI/qSlicerDataDialog.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,38 @@ void qSlicerDataDialogPrivate::addDirectory(const QDir& directory)
bool recursive = true;
QDir::Filters filters =
QDir::AllDirs | QDir::Files | QDir::Readable | QDir::NoDotAndDotDot;
QFileInfoList fileInfoList = directory.entryInfoList(filters);

//
// check to see if any readers recognize the directory contents
// and provide an archetype.
//
qSlicerCoreIOManager* coreIOManager =
qSlicerCoreApplication::application()->coreIOManager();
qSlicerIO::IOProperties ioProperties;
QFileInfo archetypeEntry;
if (coreIOManager->examineFileInfoList(fileInfoList, archetypeEntry, ioProperties))
{
this->addFile(archetypeEntry);
QString filePath = archetypeEntry.absoluteFilePath();
QList<QTableWidgetItem *> items = this->FileWidget->findItems(filePath, Qt::MatchExactly);
if (items.isEmpty())
{
qWarning() << "Couldn't add archetype widget for file: " << filePath;
}
else
{
QTableWidgetItem *item = items[0];
QWidget *cellWidget = this->FileWidget->cellWidget(item->row(), OptionsColumn);
qSlicerIOOptionsWidget *ioOptionsWidget = dynamic_cast<qSlicerIOOptionsWidget *> (cellWidget);
ioOptionsWidget->updateGUI(ioProperties);
}
}

//
// now add any files and directories that weren't filtered
// out by the ioManager
//
foreach(QFileInfo entry, directory.entryInfoList(filters))
{
if (entry.isFile())
Expand Down

0 comments on commit 81b744b

Please sign in to comment.