Skip to content

Commit 81b744b

Browse files
committed
ENH: adds hook for loading directory archetypes
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.
1 parent 7c5c6ee commit 81b744b

File tree

5 files changed

+78
-1
lines changed

5 files changed

+78
-1
lines changed

Base/QTCore/qSlicerCoreIOManager.cxx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,3 +781,18 @@ void qSlicerCoreIOManager::setDefaultSceneFileType(QString fileType)
781781
Q_D(qSlicerCoreIOManager);
782782
d->DefaultSceneFileType = fileType;
783783
}
784+
785+
//-----------------------------------------------------------------------------
786+
bool qSlicerCoreIOManager::examineFileInfoList(QFileInfoList &fileInfoList, QFileInfo &archetypeFileInfo, qSlicerIO::IOProperties &ioProperties)const
787+
{
788+
Q_D(const qSlicerCoreIOManager);
789+
QList<qSlicerFileReader*> res;
790+
foreach(qSlicerFileReader* reader, d->Readers)
791+
{
792+
if (reader->examineFileInfoList(fileInfoList, archetypeFileInfo, ioProperties))
793+
{
794+
return (true);
795+
}
796+
}
797+
return (false);
798+
}

Base/QTCore/qSlicerCoreIOManager.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@
2222
#define __qSlicerCoreIOManager_h
2323

2424
// Qt includes
25-
#include <QList>
25+
#include <QFileInfo>
2626
#include <QImage>
27+
#include <QList>
2728
#include <QMap>
2829
#include <QObject>
2930
#include <QVariantMap>
@@ -170,6 +171,21 @@ class Q_SLICER_BASE_QTCORE_EXPORT qSlicerCoreIOManager:public QObject
170171
/// Defines the file format that should be offered by default when the scene is saved.
171172
Q_INVOKABLE QString defaultSceneFileType()const;
172173

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

175191
/// Defines the file format that should be offered by default when the scene is saved.

Base/QTCore/qSlicerFileReader.cxx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,9 @@ QStringList qSlicerFileReader::loadedNodes()const
119119
Q_D(const qSlicerFileReader);
120120
return d->LoadedNodes;
121121
}
122+
123+
//----------------------------------------------------------------------------
124+
bool qSlicerFileReader::examineFileInfoList(QFileInfoList &fileInfoList, QFileInfo archetypeEntry, qSlicerIO::IOProperties &ioProperties)const
125+
{
126+
return(false);
127+
}

Base/QTCore/qSlicerFileReader.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#ifndef __qSlicerFileReader_h
2222
#define __qSlicerFileReader_h
2323

24+
// Qt includes
25+
#include <QFileInfo>
26+
2427
// QtCore includes
2528
#include "qSlicerIO.h"
2629
#include "qSlicerBaseQTCoreExport.h"
@@ -64,6 +67,11 @@ class Q_SLICER_BASE_QTCORE_EXPORT qSlicerFileReader
6467
/// \sa setLoadedNodes(), load()
6568
QStringList loadedNodes()const;
6669

70+
/// Implements the file list examination for the corresponding method in the core
71+
/// IO manager.
72+
/// \sa qSlicerCoreIOManager
73+
virtual bool examineFileInfoList(QFileInfoList &fileInfoList, QFileInfo archetypeEntry, qSlicerIO::IOProperties &ioProperties)const;
74+
6775
protected:
6876
/// Must be called in load() on success with the list of nodes added into the
6977
/// scene.

Base/QTGUI/qSlicerDataDialog.cxx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,38 @@ void qSlicerDataDialogPrivate::addDirectory(const QDir& directory)
163163
bool recursive = true;
164164
QDir::Filters filters =
165165
QDir::AllDirs | QDir::Files | QDir::Readable | QDir::NoDotAndDotDot;
166+
QFileInfoList fileInfoList = directory.entryInfoList(filters);
167+
168+
//
169+
// check to see if any readers recognize the directory contents
170+
// and provide an archetype.
171+
//
172+
qSlicerCoreIOManager* coreIOManager =
173+
qSlicerCoreApplication::application()->coreIOManager();
174+
qSlicerIO::IOProperties ioProperties;
175+
QFileInfo archetypeEntry;
176+
if (coreIOManager->examineFileInfoList(fileInfoList, archetypeEntry, ioProperties))
177+
{
178+
this->addFile(archetypeEntry);
179+
QString filePath = archetypeEntry.absoluteFilePath();
180+
QList<QTableWidgetItem *> items = this->FileWidget->findItems(filePath, Qt::MatchExactly);
181+
if (items.isEmpty())
182+
{
183+
qWarning() << "Couldn't add archetype widget for file: " << filePath;
184+
}
185+
else
186+
{
187+
QTableWidgetItem *item = items[0];
188+
QWidget *cellWidget = this->FileWidget->cellWidget(item->row(), OptionsColumn);
189+
qSlicerIOOptionsWidget *ioOptionsWidget = dynamic_cast<qSlicerIOOptionsWidget *> (cellWidget);
190+
ioOptionsWidget->updateGUI(ioProperties);
191+
}
192+
}
193+
194+
//
195+
// now add any files and directories that weren't filtered
196+
// out by the ioManager
197+
//
166198
foreach(QFileInfo entry, directory.entryInfoList(filters))
167199
{
168200
if (entry.isFile())

0 commit comments

Comments
 (0)