Skip to content
Snippets Groups Projects
Commit 017a340e authored by Peterson, Peter's avatar Peterson, Peter
Browse files

Merge remote-tracking branch 'origin/17358_multiplefile_optional'

parents 66ddd0a7 1ef384e4
No related branches found
No related tags found
No related merge requests found
...@@ -129,21 +129,22 @@ namespace API { ...@@ -129,21 +129,22 @@ namespace API {
class DLLExport MultipleFileProperty class DLLExport MultipleFileProperty
: public Kernel::PropertyWithValue<std::vector<std::vector<std::string>>> { : public Kernel::PropertyWithValue<std::vector<std::vector<std::string>>> {
public: public:
/// Constructor MultipleFileProperty(
const std::string &name, unsigned int action,
const std::vector<std::string> &exts = std::vector<std::string>());
MultipleFileProperty( MultipleFileProperty(
const std::string &name, const std::string &name,
const std::vector<std::string> &exts = std::vector<std::string>()); const std::vector<std::string> &exts = std::vector<std::string>());
/// 'Virtual copy constructor
MultipleFileProperty *clone() const override { MultipleFileProperty *clone() const override {
return new MultipleFileProperty(*this); return new MultipleFileProperty(*this);
} }
/// Overridden functions to accomodate std::vector<std::vector<std::string>>>
/// structure of this property.
std::string setValue(const std::string &propValue) override; std::string setValue(const std::string &propValue) override;
std::string value() const override; std::string value() const override;
std::string getDefault() const override; std::string getDefault() const override;
bool isOptional() const;
/// @return the vector of suggested extensions. For use in GUIs showing files. /// @return the vector of suggested extensions. For use in GUIs showing files.
std::vector<std::string> getExts() const { return m_exts; } std::vector<std::string> getExts() const { return m_exts; }
...@@ -156,6 +157,8 @@ public: ...@@ -156,6 +157,8 @@ public:
operator=; operator=;
private: private:
/// Returns a string depending on whether an empty value is valid
std::string isEmptyValueValid() const;
std::string setValueAsSingleFile(const std::string &propValue); std::string setValueAsSingleFile(const std::string &propValue);
std::string setValueAsMultipleFiles(const std::string &propValue); std::string setValueAsMultipleFiles(const std::string &propValue);
/// Whether or not the user has turned on multifile loading. /// Whether or not the user has turned on multifile loading.
...@@ -168,6 +171,9 @@ private: ...@@ -168,6 +171,9 @@ private:
/// The default file extension associated with the type of file this property /// The default file extension associated with the type of file this property
/// will handle /// will handle
std::string m_defaultExt; std::string m_defaultExt;
/// The action type of this property
/// Load (dafault) or OptionalLoad are supported
unsigned int m_action;
}; };
} // namespace API } // namespace API
......
...@@ -37,17 +37,27 @@ bool doesNotContainWildCard(const std::string &ext) { ...@@ -37,17 +37,27 @@ bool doesNotContainWildCard(const std::string &ext) {
namespace Mantid { namespace Mantid {
namespace API { namespace API {
/** /**
* Constructor * Alternative constructor with action
* *
* @param name :: The name of the property * @param name :: The name of the property
* @param exts :: The allowed/suggested extensions * @param action :: File action
* @param exts :: The allowed/suggested extensions
*/ */
MultipleFileProperty::MultipleFileProperty(const std::string &name, MultipleFileProperty::MultipleFileProperty(const std::string &name,
unsigned int action,
const std::vector<std::string> &exts) const std::vector<std::string> &exts)
: PropertyWithValue<std::vector<std::vector<std::string>>>( : PropertyWithValue<std::vector<std::vector<std::string>>>(
name, std::vector<std::vector<std::string>>(), name, std::vector<std::vector<std::string>>(),
boost::make_shared<MultiFileValidator>(exts), Direction::Input), boost::make_shared<MultiFileValidator>(
m_multiFileLoadingEnabled(), m_exts(), m_parser(), m_defaultExt("") { exts, (action == FileProperty::Load)),
Direction::Input) {
if (action != FileProperty::Load && action != FileProperty::OptionalLoad) {
/// raise error for unsupported actions
throw std::runtime_error(
"Specified action is not supported for MultipleFileProperty");
} else {
m_action = action;
}
std::string allowMultiFileLoading = std::string allowMultiFileLoading =
Kernel::ConfigService::Instance().getString("loading.multifile"); Kernel::ConfigService::Instance().getString("loading.multifile");
...@@ -61,6 +71,35 @@ MultipleFileProperty::MultipleFileProperty(const std::string &name, ...@@ -61,6 +71,35 @@ MultipleFileProperty::MultipleFileProperty(const std::string &name,
m_exts.push_back(ext); m_exts.push_back(ext);
} }
/**
* Default constructor with default action
*
* @param name :: The name of the property
* @param exts :: The allowed/suggested extensions
*/
MultipleFileProperty::MultipleFileProperty(const std::string &name,
const std::vector<std::string> &exts)
: MultipleFileProperty(name, FileProperty::Load, exts) {}
/**
* Check if this property is optional
* @returns True if the property is optinal, false otherwise
*/
bool MultipleFileProperty::isOptional() const {
return (m_action == FileProperty::OptionalLoad);
}
/**
* @returns Empty string if empty value is valid, error message otherwise
*/
std::string MultipleFileProperty::isEmptyValueValid() const {
if (isOptional()) {
return "";
} else {
return "No file specified.";
}
}
/** /**
* Convert the given propValue into a comma and plus separated list of full * Convert the given propValue into a comma and plus separated list of full
*filenames, and pass to the parent's *filenames, and pass to the parent's
...@@ -74,8 +113,11 @@ MultipleFileProperty::MultipleFileProperty(const std::string &name, ...@@ -74,8 +113,11 @@ MultipleFileProperty::MultipleFileProperty(const std::string &name,
*An empty string indicates success. *An empty string indicates success.
*/ */
std::string MultipleFileProperty::setValue(const std::string &propValue) { std::string MultipleFileProperty::setValue(const std::string &propValue) {
// No empty value is allowed. // No empty value is allowed, unless optional.
if (propValue.empty()) // This is yet aditional check that is beyond the underlying
// MultiFileValidator,
// so isOptional needs to be inspected here as well
if (propValue.empty() && !isOptional())
return "No file(s) specified."; return "No file(s) specified.";
// If multiple file loading is disabled, then set value assuming it is a // If multiple file loading is disabled, then set value assuming it is a
......
#ifndef MANTID_API_MULTIPLEFILEPROPERTYTEST_H_ #ifndef MANTID_API_MULTIPLEFILEPROPERTYTEST_H_
#define MANTID_API_MULTIPLEFILEPROPERTYTEST_H_ #define MANTID_API_MULTIPLEFILEPROPERTYTEST_H_
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/MultipleFileProperty.h" #include "MantidAPI/MultipleFileProperty.h"
#include "MantidKernel/System.h" #include "MantidKernel/System.h"
#include "MantidKernel/Timer.h" #include "MantidKernel/Timer.h"
...@@ -17,6 +18,7 @@ ...@@ -17,6 +18,7 @@
using namespace Mantid; using namespace Mantid;
using namespace Mantid::API; using namespace Mantid::API;
using Mantid::API::FileProperty;
////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////
// Helper functions. // Helper functions.
...@@ -616,6 +618,18 @@ public: ...@@ -616,6 +618,18 @@ public:
TS_ASSERT_EQUALS(fileNames[0].size(), 1); TS_ASSERT_EQUALS(fileNames[0].size(), 1);
} }
void test_multiFileOptionalLoad() {
MultipleFileProperty p("Filename", FileProperty::OptionalLoad);
p.setValue("myJunkFile.nxs");
TS_ASSERT(p.isValid().empty());
}
void test_multiFileOptionalLoadEmpty() {
MultipleFileProperty p("Filename", FileProperty::OptionalLoad);
p.setValue("");
TS_ASSERT(p.isValid().empty());
}
private: private:
////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////
// Private helper functions. // Private helper functions.
......
...@@ -47,7 +47,8 @@ class MANTID_KERNEL_DLL MultiFileValidator ...@@ -47,7 +47,8 @@ class MANTID_KERNEL_DLL MultiFileValidator
public: public:
MultiFileValidator(); MultiFileValidator();
MultiFileValidator(const MultiFileValidator &mfv); MultiFileValidator(const MultiFileValidator &mfv);
explicit MultiFileValidator(const std::vector<std::string> &extensions); explicit MultiFileValidator(const std::vector<std::string> &extensions,
bool testFilesExist = true);
IValidator_sptr clone() const override; IValidator_sptr clone() const override;
......
...@@ -21,11 +21,12 @@ MultiFileValidator::MultiFileValidator(const MultiFileValidator &mfv) ...@@ -21,11 +21,12 @@ MultiFileValidator::MultiFileValidator(const MultiFileValidator &mfv)
/** Constructor /** Constructor
* @param extensions :: The permitted file extensions (e.g. .RAW) * @param extensions :: The permitted file extensions (e.g. .RAW)
* @param testFilesExist :: If to check if files exist
*/ */
MultiFileValidator::MultiFileValidator( MultiFileValidator::MultiFileValidator(
const std::vector<std::string> &extensions) const std::vector<std::string> &extensions, bool testFilesExist)
: TypedValidator<std::vector<std::vector<std::string>>>(), : TypedValidator<std::vector<std::vector<std::string>>>(),
m_fileValidator(extensions, true) {} m_fileValidator(extensions, testFilesExist) {}
/// Returns the set of valid values /// Returns the set of valid values
std::vector<std::string> MultiFileValidator::allowedValues() const { std::vector<std::string> MultiFileValidator::allowedValues() const {
......
...@@ -125,6 +125,20 @@ public: ...@@ -125,6 +125,20 @@ public:
file_val.isValid(std::vector<std::vector<std::string>>()).empty(), file_val.isValid(std::vector<std::vector<std::string>>()).empty(),
false); false);
} }
void testFailsOnNonExistingFiles() {
std::vector<std::string> vec{"foo"};
MultiFileValidator file_val(vec);
std::vector<std::vector<std::string>> file{{"myJunkFile.foo"}};
TS_ASSERT(!file_val.isValid(file).empty());
}
void testPassesOnNonExistingFiles() {
std::vector<std::string> vec{"foo"};
MultiFileValidator file_val(vec, false);
std::vector<std::vector<std::string>> file{{"myJunkFile.foo"}};
TS_ASSERT(file_val.isValid(file).empty());
}
}; };
#endif /*MULTIFILEVALIDATORTEST_H_*/ #endif /*MULTIFILEVALIDATORTEST_H_*/
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/MultipleFileProperty.h" #include "MantidAPI/MultipleFileProperty.h"
#include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h" #include "MantidPythonInterface/kernel/Converters/PySequenceToVector.h"
#include "MantidPythonInterface/kernel/IsNone.h" #include "MantidPythonInterface/kernel/IsNone.h"
...@@ -7,6 +8,7 @@ ...@@ -7,6 +8,7 @@
#include <boost/python/make_constructor.hpp> #include <boost/python/make_constructor.hpp>
#include <boost/python/str.hpp> #include <boost/python/str.hpp>
using Mantid::API::FileProperty;
using Mantid::API::MultipleFileProperty; using Mantid::API::MultipleFileProperty;
using Mantid::Kernel::PropertyWithValue; using Mantid::Kernel::PropertyWithValue;
using Mantid::PythonInterface::Converters::PySequenceToVector; using Mantid::PythonInterface::Converters::PySequenceToVector;
...@@ -45,8 +47,9 @@ boost::python::object valueAsPyObject(MultipleFileProperty &self) { ...@@ -45,8 +47,9 @@ boost::python::object valueAsPyObject(MultipleFileProperty &self) {
} }
MultipleFileProperty * MultipleFileProperty *
createMultipleFileProperty(const std::string &name, createMultipleFilePropertyWithAction(const std::string &name,
const object &extensions = object()) { unsigned int action,
const object &extensions = object()) {
std::vector<std::string> extsAsVector; std::vector<std::string> extsAsVector;
if (!Mantid::PythonInterface::isNone(extensions)) { if (!Mantid::PythonInterface::isNone(extensions)) {
extract<std::string> extractor(extensions); extract<std::string> extractor(extensions);
...@@ -56,7 +59,14 @@ createMultipleFileProperty(const std::string &name, ...@@ -56,7 +59,14 @@ createMultipleFileProperty(const std::string &name,
extsAsVector = PySequenceToVector<std::string>(extensions)(); extsAsVector = PySequenceToVector<std::string>(extensions)();
} }
} }
return new MultipleFileProperty(name, extsAsVector); return new MultipleFileProperty(name, action, extsAsVector);
}
MultipleFileProperty *
createMultipleFileProperty(const std::string &name,
const object &extensions = object()) {
return createMultipleFilePropertyWithAction(
name, FileProperty::FileAction::Load, extensions);
} }
} }
...@@ -70,6 +80,10 @@ void export_MultipleFileProperty() { ...@@ -70,6 +80,10 @@ void export_MultipleFileProperty() {
.def("__init__", make_constructor( .def("__init__", make_constructor(
&createMultipleFileProperty, default_call_policies(), &createMultipleFileProperty, default_call_policies(),
(arg("name"), arg("extensions") = object()))) (arg("name"), arg("extensions") = object())))
.def("__init__",
make_constructor(
&createMultipleFilePropertyWithAction, default_call_policies(),
(arg("name"), arg("action"), arg("extensions") = object())))
// Override the base class one to do something more appropriate // Override the base class one to do something more appropriate
.add_property("value", &valueAsPyObject); .add_property("value", &valueAsPyObject);
} }
...@@ -50,8 +50,9 @@ or, if creating using an already existing vector: ...@@ -50,8 +50,9 @@ or, if creating using an already existing vector:
File Properties File Properties
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
These properties are for capturing and holding the path and filename to There are two file properties: ``FileProperty`` and ``MultipleFileProperty``.
an external file. File properties have a FileAction property that These properties are for capturing and holding the path and filenames to
external file (s). File properties have a FileAction property that
controls it's purpose and behaviour. controls it's purpose and behaviour.
Save :to specify a file to write to, the file may or may not exist Save :to specify a file to write to, the file may or may not exist
...@@ -65,6 +66,8 @@ If the file property is has a FileAction of Load as is given a relative ...@@ -65,6 +66,8 @@ If the file property is has a FileAction of Load as is given a relative
path (such as "input.txt" or "\\data\\input.txt" as its value it will path (such as "input.txt" or "\\data\\input.txt" as its value it will
search for matching files in this order: search for matching files in this order:
Note, that ``MultipleFileProperty`` supports only Load (default) and OptionalLoad actions.
#. The current directory #. The current directory
#. The entries in order from the datasearch.directories entry in the #. The entries in order from the datasearch.directories entry in the
:ref:`Properties File <Properties File>` :ref:`Properties File <Properties File>`
...@@ -158,6 +161,8 @@ The validators currently included in Mantid are: ...@@ -158,6 +161,8 @@ The validators currently included in Mantid are:
set of values. set of values.
- FileValidator - ensures that a file (given as a string property) - FileValidator - ensures that a file (given as a string property)
exists (used internally by the FileProperty). exists (used internally by the FileProperty).
- MultiFileValidator - ensures that each file in a given list exists
(used internally by the MultipleFileProperty).
In addition, there are a number of validators specifically for use with In addition, there are a number of validators specifically for use with
Workspace properties: Workspace properties:
......
...@@ -23,6 +23,8 @@ Concepts ...@@ -23,6 +23,8 @@ Concepts
undefined and infinite values and errors will be zeroed. undefined and infinite values and errors will be zeroed.
- ``Lattice`` : Allow setting a UB matrix with negative determinant (improper rotation) - ``Lattice`` : Allow setting a UB matrix with negative determinant (improper rotation)
- ``MultipleFileProperty`` : will now support also ``OptionalLoad`` ``FileAction`` (similar to ``FileProperty``).
Algorithms Algorithms
---------- ----------
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment