diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/MultipleFileProperty.h b/Code/Mantid/Framework/API/inc/MantidAPI/MultipleFileProperty.h index 4eeb02eeeab2f5df851b2e26bcde15d6fed818c4..35d94fe3a9b7b940bff18776fb8da0b19de11b20 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/MultipleFileProperty.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/MultipleFileProperty.h @@ -1,7 +1,6 @@ #ifndef MANTID_API_MULTIPLEFILEPROPERTY_H_ #define MANTID_API_MULTIPLEFILEPROPERTY_H_ -#include "MantidKernel/Logger.h" #include "MantidKernel/PropertyWithValue.h" #include "MantidKernel/System.h" #include "MantidKernel/MultiFileNameParser.h" @@ -13,70 +12,8 @@ namespace Mantid namespace API { - /** - A property to allow a user to specify multiple files to load. - - The current functionality is such that there are two basic forms of syntax. For the puposes - of documentation we'll call these the "Long Form" and "Short Form". - - ------------------------------------------------------------------------------------------------------ - [A] Short Form - - These strings are of the format "[dir][inst][under][runs][ext]" where: - - [dir] (Optional) = The OS-specific file directory, e.g. "c:/data/" - [inst] (Optional) = The instrument name, e.g. "IRS" or "PG3". - [under] (Optional) = Some instrument filenames require an underscore. - [runs] (Required) = The run numbers, e.g. "0102, 0110-0115, 0120, 0130:0140:2" - [ext] (Optional) = The file extension, e.g. ".raw" - - For optional values, defaults or user settings are used where necessary. + /** A property to allow a user to select multiple files to load. - For [runs], users specify lists and ranges of runs using comma, plus, minus and colon. Some examples: - - "TSC0001,0002" = Runs 1 and 2 of the TOSCA instrument are to be loaded. - "0003+0004" = Runs 3 and 4 of the default instrument are to be loaded and added together. - "0005:0009.raw" = The raw files containing runs 5 to 9 of the default instrument are to be loaded. - "c:/data/0010-0014" = The files in "c:/data/" containing runs 10 to 14 of the default instrument are - to be loaded and added together. - "IRS0020:0028:2.nxs" = The nexus files containing runs 20, 22, 24, 26 and 28 for IRIS are to be loaded. - "INST_0030-0038:3" = Runs 30, 33, and 36 of INST are to be loaded and added together. - - ------------------------------------------------------------------------------------------------------ - [B] Long Form - - These strings are of the format "[[short_form][operator]]...[short_form]" where: - - [short_form] = [dir][inst][under][runs][ext], which is the "Short Form" outlined above. - [operator] = Either a comma or a plus. - - Some examples: - - "TSC0001,TSC0002+0003" = Runs 1, 2 and 3 of the TOSCA instrument should be loaded, but 2 and 3 - are added together. - "TSC0005+TSC0006,TSC0007.raw" = Runs 5 and 6 as well as the raw file containing run 7 of the TOSCA - instrument should be loaded, but 5 and 6 are added together. - - ------------------------------------------------------------------------------------------------------ - NOTES: - - [1] Presently, we disallow more complex algebra such as "TSC0005,0006+TSC0007". In such a case it is - ambiguous whether or not the user wishes to just add run 7 to 6, or add run 7 to both 5 and 6. - - [2] The "Short Form" is parsed by the Kernel::MultiFileNameParsing::Parser class, whereas this class is - responsible for splitting up the Long Form. - - [3] The functionality of this class is such that all strings are stored only after being converted to - the Long Form, and all filenames are fully resolved. For example "0005,0006+0007" is stored as - "[dir][inst][under]0005[ext],[dir][inst][under]0006[ext]+[dir][inst][under]0007[ext]". - - [4] The default functionality of this Property can be changed to emulate a simple FileProperty - to do - this, the user must change the properties file. Disabling multi file loading in this way will allow - users to use "," and "+" in their filenames, and in this case we use the dummy "" delimiters to call - toValue and toString. - - ------------------------------------------------------------------------------------------------------ - Copyright © 2011 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory This file is part of Mantid. @@ -108,10 +45,8 @@ namespace API /// 'Virtual copy constructor virtual MultipleFileProperty* clone() const { return new MultipleFileProperty(*this); } - /// Overridden functions to accomodate std::vector<std::vector<std::string>>> structure of this property. + /// Overridden setValue method virtual std::string setValue(const std::string & propValue); - virtual std::string value() const; - virtual std::string getDefault() const; /// @return the vector of suggested extensions. For use in GUIs showing files. std::set<std::string> getExts() const @@ -130,17 +65,12 @@ namespace API static std::vector<std::string> flattenFileNames(const std::vector<std::vector<std::string> > & fileNames); private: - /// Whether or not the user has turned on multifile loading. - bool m_multiFileLoadingEnabled; - /// Suggested extensions std::vector<std::string> m_exts; /// Parser used to parse multi-file strings. Kernel::MultiFileNameParsing::Parser m_parser; ///The default file extension associated with the type of file this property will handle std::string m_defaultExt; - /// Reference to the logger class - Kernel::Logger& g_log; }; diff --git a/Code/Mantid/Framework/API/src/MultipleFileProperty.cpp b/Code/Mantid/Framework/API/src/MultipleFileProperty.cpp index 536968a94169453d570c9f3351c429e7a53fa5d4..952db89287819bed62c211c80254224ac79caa36 100644 --- a/Code/Mantid/Framework/API/src/MultipleFileProperty.cpp +++ b/Code/Mantid/Framework/API/src/MultipleFileProperty.cpp @@ -1,18 +1,15 @@ - -#include "MantidAPI/FileProperty.h" -#include "MantidAPI/FileFinder.h" #include "MantidAPI/MultipleFileProperty.h" - -#include "MantidKernel/ConfigService.h" +#include "MantidAPI/FileProperty.h" +#include "MantidKernel/System.h" #include "MantidKernel/MultiFileValidator.h" #include "MantidKernel/Property.h" -#include "MantidKernel/System.h" - #include <Poco/Path.h> -#include <boost/algorithm/string.hpp> -#include <boost/regex.hpp> +#include "MantidAPI/FileFinder.h" #include <ctype.h> + +#include <boost/algorithm/string.hpp> + #include <functional> #include <numeric> @@ -26,10 +23,6 @@ namespace API // Forward declarations namespace { - /** - * A functor that stores a list of extensions and then accumulates the full, resolved file - * names that are passed to it on to an output string. Used with the accumulate STL algorithm. - */ class AppendFullFileName { public: @@ -44,48 +37,35 @@ namespace API std::vector<std::vector<std::string> > unflattenFileNames( const std::vector<std::string> & flattenedFileNames); - - std::string toSingleString(const std::vector<std::vector<std::string>> & filenames); } - /** - * Constructor + /** Constructor * * @param name :: The name of the property * @param exts :: The allowed/suggested extensions - * @param optional :: If true, the property is optional + * @param optional :: If ture, the property is optional */ MultipleFileProperty::MultipleFileProperty( const std::string & name, const std::vector<std::string> & exts - ) : PropertyWithValue<std::vector<std::vector<std::string> > >( name, - std::vector<std::vector<std::string> >(), boost::make_shared<MultiFileValidator>(exts), Direction::Input), - m_multiFileLoadingEnabled(), + ) : PropertyWithValue<std::vector<std::vector<std::string> > >( + name, + std::vector<std::vector<std::string> >(), + boost::make_shared<MultiFileValidator>(exts), + Direction::Input), m_exts(exts), m_parser(), - m_defaultExt(""), - g_log(Kernel::Logger::get("MultipleFileProperty")) - { - std::string allowMultiFileLoading = Kernel::ConfigService::Instance().getString("loading.multifile"); + m_defaultExt("") + {} - if( boost::iequals(allowMultiFileLoading, "On") ) - m_multiFileLoadingEnabled = true; - else - m_multiFileLoadingEnabled = false; - } - - /** - * Destructor + //---------------------------------------------------------------------------------------------- + /** Destructor */ MultipleFileProperty::~MultipleFileProperty() {} - /** - * Convert the given propValue into a comma and plus separated list of full filenames, and pass to the parent's - * setValue method to store as a vector of vector of strings. - * - * READ HEADER FILE DOCUMENTATION FOR A MORE DETAILED OVERVIEW. + /** Set the value, with a comma- and plus-separated string of filenames * - * @param propValue :: A string of the allowed format, indicating the user's choice of files. + * @param propValue :: comma- and plus-separated string of filenames * @return A string indicating the outcome of the attempt to set the property. An empty string indicates success. */ std::string MultipleFileProperty::setValue(const std::string & propValue) @@ -94,163 +74,74 @@ namespace API if( propValue.empty()) return "No file(s) specified."; - if( ! m_multiFileLoadingEnabled ) - { - g_log.debug("MultiFile loading is not enabled, acting as standard FileProperty."); - - // Use a slave FileProperty to do the job for us. - FileProperty slaveFileProp( "Slave", "", FileProperty::Load, m_exts, Direction::Input); - - std::string error = slaveFileProp.setValue(propValue); - - if(!error.empty()) - return error; - - // Store. - try - { - std::vector<std::vector<std::string>> result; - toValue(slaveFileProp(), result, "", ""); - PropertyWithValue<std::vector<std::vector<std::string> > >::operator=(result); - return ""; - } - catch ( std::invalid_argument& except) - { - g_log.debug() << "Could not set property " << name() << ": " << except.what(); - return except.what(); - } - return ""; - } - - const std::string INVALID = "\\+\\+|,,|\\+,|,\\+"; - boost::smatch invalid_substring; - if( boost::regex_search( - propValue.begin(), propValue.end(), - invalid_substring, - boost::regex(INVALID)) ) - return "Unable to parse filename due to an empty token."; - - // Else if multifile loading *is* enabled, then users make the concession that they cannot use "," or "+" in - // directory names; they are used as operators only. - const std::string NUM_COMMA_ALPHA = "(?<=\\d)\\s*,\\s*(?=\\D)"; - const std::string ALPHA_COMMA_ALPHA = "(?<=\\D)\\s*,\\s*(?=\\D)"; - const std::string NUM_PLUS_ALPHA = "(?<=\\d)\\s*\\+\\s*(?=\\D)"; - const std::string ALPHA_PLUS_ALPHA = "(?<=\\D)\\s*\\+\\s*(?=\\D)"; - const std::string COMMA_OPERATORS = NUM_COMMA_ALPHA + "|" + ALPHA_COMMA_ALPHA; - const std::string PLUS_OPERATORS = NUM_PLUS_ALPHA + "|" + ALPHA_PLUS_ALPHA; + std::string value = propValue; std::stringstream errorMsg; - // Tokenise on allowed comma operators, and iterate over each token. - boost::sregex_token_iterator end; - boost::sregex_token_iterator commaToken( - propValue.begin(), propValue.end(), - boost::regex(COMMA_OPERATORS), -1); - - std::vector<std::vector<std::string> > fileNames; - + // Assume a format of "dir/inst_1,2,...n.raw", and try to parse using parser. try { - for(; commaToken != end; ++commaToken) - { - const std::string comma = commaToken->str(); - - // Tokenise on allowed plus operators, and iterate over each token. - boost::sregex_token_iterator plusToken( - comma.begin(), comma.end(), - boost::regex(PLUS_OPERATORS, boost::regex_constants::perl), -1); - - std::vector<std::vector<std::vector<std::string>>> temp; - - for(; plusToken != end; ++plusToken) - { - const std::string plus = plusToken->str(); - - try - { - m_parser.parse(plus); - } - catch(const std::runtime_error & re) - { - errorMsg << "Unable to parse runs: \"" << re.what() << "\". "; - } - - std::vector<std::vector<std::string>> f = m_parser.fileNames(); - - // If there are no files, then we should use this token as it was passed to the property, - // in its untampered form. This will enable us to deal with the case where a user is trying to - // load a single (and possibly existing) file within a token, but which has unexpected zero - // padding, or some other anomaly. - if( flattenFileNames(f).size() == 0 ) - f.push_back(std::vector<std::string>(1, plus)); - - temp.push_back(f); - } - - // See [3] in header documentation. Basically, for reasons of ambiguity, we cant add - // together plusTokens if they contain more than one file. Throw on any instances of this. - if( temp.size() > 1 ) - { - for(auto tempFiles = temp.begin(); tempFiles != temp.end(); ++tempFiles) - if( flattenFileNames(*tempFiles).size() > 1 ) - throw std::runtime_error("Adding a range of files to another file(s) is not currently supported."); - } - - for( auto multifile = temp.begin(); multifile != temp.end(); ++multifile ) - fileNames.insert( - fileNames.end(), - multifile->begin(), multifile->end()); - } + m_parser.parse(value); } catch(const std::runtime_error & re) { - errorMsg << "Unable to parse runs: \"" << re.what() << "\". "; - return errorMsg.str(); + errorMsg << "Unable to parse multi file runs: \"" << re.what() << "\". "; } - if(fileNames.size() == 1 && fileNames[0].size() == 1) - fileNames[0][0] = propValue; + std::vector<std::vector<std::string> > fileNames = m_parser.fileNames(); - - std::string fullFileNames = ""; - try + AppendFullFileName appendFullFileName(m_exts); + std::string fullFileNames(""); + + // If unsuccessful, then assume a format of: + // + // "dir/inst_1.raw, dir/inst_2.raw, ... dir/inst_n.raw" (where n may equal 1). + // + // Tokenise on commas, and and try to find full files names of each token. + if(fileNames.empty()) { - // Use an AppendFullFileName functor object with std::accumulate to append - // full filenames to a single string. - AppendFullFileName appendFullFileName(m_exts); - fullFileNames = std::accumulate( - fileNames.begin(), fileNames.end(), - std::string(""), - appendFullFileName); + std::vector<std::string> tokens; + tokens = boost::split(tokens, value, boost::is_any_of(",")); + fileNames = unflattenFileNames(tokens); + try + { + fullFileNames = std::accumulate( + fileNames.begin(), fileNames.end(), + std::string(""), + appendFullFileName); + } + catch(const std::runtime_error & re) + { + errorMsg << "Tried to find as single file(s), but also failed: \"" << re.what() << "\"."; + return errorMsg.str(); + } } - catch(const std::runtime_error & re) + // Else, for each file name in the vector, change it into a full file name where possible, + // then append it onto a comma- and plus-separated string. + else { - return re.what(); - } + // If there is only one file, then we should use the string passed to the property, which + // has not been tampered with. This will enable us to deal with the case where a user is + // trying to load a single file with incorrect zero padding, or some other anomaly. + if(fileNames.size() == 1 && fileNames[0].size() == 1) + fileNames[0][0] = propValue; + + try + { + fullFileNames = std::accumulate( + fileNames.begin(), fileNames.end(), + std::string(""), + appendFullFileName); + } + catch(const std::runtime_error & re) + { + return re.what(); + } + } // Now re-set the value using the full paths found. return PropertyWithValue<std::vector<std::vector<std::string> > >::setValue(fullFileNames); } - - std::string MultipleFileProperty::value() const - { - if( ! m_multiFileLoadingEnabled ) - return toString(m_value, "", ""); - - return toString(m_value); - } - - /** - * Get the value the property was initialised with -its default value - * @return The default value - */ - std::string MultipleFileProperty::getDefault() const - { - if( ! m_multiFileLoadingEnabled ) - return toString(m_initialValue, "", ""); - - return toString(m_initialValue); - } /** * A convenience function for the cases where we dont use the MultiFileProperty to @@ -295,14 +186,12 @@ namespace API m_exts(exts) {} - /** - * Takes in a vector of filenames, tries to find their full path if possible, then cumulatively appends - * them to the result string. - * - * @param result :: the cumulative result so far - * @param fileNames :: the name to look for, and append to the result - * @return the cumulative result, after the filenames have been appended. - */ + /** Takes in a vector of filenames, tries to find their full path if possible, then cumulatively appends + * them to the result string. + * @param result :: the cumulative result so far + * @param fileNames :: the name to look for, and append to the result + * @return the cumulative result, after the filenames have been appended. + */ std::string & AppendFullFileName::operator()(std::string & result, const std::vector<std::string> & fileNames) { // Append nothing if there are no file names to add. @@ -326,14 +215,12 @@ namespace API return result; } - /** - * Takes in a filename, tries to find it's full path if possible, then cumulatively appends it to a result string. - * - * @param result :: the cumulative result so far - * @param fileName :: the name to look for, and append to the result - * @return the cumulative result, after the filename has been appended. - * @throws std::runtime_error if an individual filename could not be set to the FileProperty object - */ + /** Takes in a filename, tries to find it's full path if possible, then cumulatively appends it to a result string. + * @param result :: the cumulative result so far + * @param fileName :: the name to look for, and append to the result + * @return the cumulative result, after the filename has been appended. + * @throws std::runtime_error if an individual filename could not be set to the FileProperty object + */ std::string & AppendFullFileName::operator()(std::string & result, const std::string & fileName) { // Append nothing if there is no file name to add. @@ -348,7 +235,12 @@ namespace API boost::algorithm::trim(value); // Initialise a "slave" FileProperty object to do all the work. - FileProperty slaveFileProp("Slave", "", FileProperty::Load, m_exts, Direction::Input); + FileProperty slaveFileProp( + "Slave", + "", + FileProperty::Load, + m_exts, + Direction::Input); std::string error = slaveFileProp.setValue(value); @@ -380,37 +272,6 @@ namespace API return unflattenedFileNames; } - - /** - * Converts a vector of vector of strings into a single comma and plus separated string. - * For example [["a", "b"],["x", "y", "z"]] into "a+b,x+y+z". - * - * @param - vector of vector of strings (filenames). - * - * @returns a single comma and plus separated string. - */ - std::string toSingleString(const std::vector<std::vector<std::string>> & filenames) - { - std::string result; - - for( auto filenameList = filenames.begin(); filenameList != filenames.end(); ++filenameList) - { - std::string innerResult = ""; - - for( auto filename = filenameList->begin(); filename != filenameList->end(); ++filename) - { - if( ! innerResult.empty() ) - innerResult += "+"; - innerResult += *filename; - } - - if( ! result.empty() ) - result += ","; - result += innerResult; - } - - return result; - } } // anonymous namespace } // namespace Mantid diff --git a/Code/Mantid/Framework/API/test/MultipleFilePropertyTest.h b/Code/Mantid/Framework/API/test/MultipleFilePropertyTest.h index 9ac93452380f4deba6ad9acd2113a7a5f10078ae..8f2e74d7556fde1a27b145e8e85596ae891759e8 100644 --- a/Code/Mantid/Framework/API/test/MultipleFilePropertyTest.h +++ b/Code/Mantid/Framework/API/test/MultipleFilePropertyTest.h @@ -16,27 +16,10 @@ using namespace Mantid::API; class MultipleFilePropertyTest : public CxxTest::TestSuite { -private: - std::string m_multiFileLoading; -public: - - void setUp() - { - // Make sure that multi file loading is enabled for each test. - m_multiFileLoading = Kernel::ConfigService::Instance().getString("loading.multifile"); - Kernel::ConfigService::Instance().setString("loading.multifile", "On"); - } - - void tearDown() - { - // Replace user's preference after the test has run. - Kernel::ConfigService::Instance().setString("loading.multifile", m_multiFileLoading); - } - +public: void test_setValue() { MultipleFileProperty p("Filename"); - // REF_L example is important since the instrument has no zero padding value. p.setValue("REF_L_32035.nxs, CSP78173.raw"); std::vector<std::vector<std::string> > filenames = p(); TS_ASSERT_EQUALS( filenames.size(), 2); @@ -62,44 +45,13 @@ public: TS_ASSERT_EQUALS(fileNames[3].size(), 1); } - void test_failsOnComplexAddition() - { - MultipleFileProperty p("Filename"); - p.setValue("MUSR15189:15190+MUSR15189"); - std::vector<std::vector<std::string>> fileNames = p(); - TS_ASSERT_EQUALS(fileNames.size(), 0); - } - - void test_failsOnBadlyFormedFilename() - { - MultipleFileProperty p("Filename"); - p.setValue("MUSR15189,,MUSR15189"); - std::vector<std::vector<std::string>> fileNames = p(); - TS_ASSERT_EQUALS(fileNames.size(), 0); - } - - void test_multiFileSwitchedOff() - { - Kernel::ConfigService::Instance().setString("loading.multifile", "Off"); - - std::string filename = "_MultipleFilePropertyTest_tempFileWithA+AndA,InTheName.txt"; - - Poco::File temp(filename); - temp.createFile(); - - MultipleFileProperty p("Filename"); - p.setValue(filename); - std::vector<std::vector<std::string>> fileNames = p(); - TS_ASSERT_EQUALS(fileNames.size(), 1); - } - void test_folderWithWhitespace() { std::string dirPath = "_MultipleFilePropertyTestDummyFolder WithWhiteSpace"; std::string filename = "TSC99999.raw"; std::string oldDataSearchDirectories = ""; - // Create a dummy folder with whitespace to use. + // Create a dummy folder with whitespace to use. Poco::File dir(dirPath); dir.createDirectories(); diff --git a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h index 96fcbd881f10f43e55065f21cfa455666094b1ce..2d4bcd4fc3cd0b650e5945e8f335e0ea2e8789d4 100644 --- a/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h +++ b/Code/Mantid/Framework/DataHandling/inc/MantidDataHandling/Load.h @@ -93,12 +93,16 @@ namespace Mantid const API::IDataFileChecker_sptr loader) const; /// Load a file to into a hidden workspace. - API::Workspace_sptr loadFileToWs(const std::string & fileName, const std::string & wsName); + API::Workspace_sptr loadFileToHiddenWs(const std::string & fileName, const std::string & wsName); /// Plus two workspaces together, "in place". API::Workspace_sptr plusWs(API::Workspace_sptr ws1, API::Workspace_sptr ws2); - /// Manually group workspaces. - API::WorkspaceGroup_sptr groupWsList(std::vector<API::Workspace_sptr> wsList); - + /// Delete a workspace with the given name. + void deleteWs(const std::string & wsName); + /// Rename a workspace with the given name. + void renameWs(const std::string & oldName, const std::string & newName); + /// Unhide the given workspace, if it is hidden. + void unhideWs(const std::string & wsName); + private: /// The base properties std::set<std::string> m_baseProps; diff --git a/Code/Mantid/Framework/DataHandling/src/Load.cpp b/Code/Mantid/Framework/DataHandling/src/Load.cpp index 16c6705bb05c358ac581bf0da5c32918555f52cc..32765530e500b3b37c752baafaf108dfa55f854d 100644 --- a/Code/Mantid/Framework/DataHandling/src/Load.cpp +++ b/Code/Mantid/Framework/DataHandling/src/Load.cpp @@ -456,32 +456,50 @@ namespace Mantid void Load::loadMultipleFiles() { MultipleFileProperty * multiFileProp = dynamic_cast<MultipleFileProperty*>(getPointerToProperty("Filename")); - const std::vector<std::vector<std::string> > allFilenames = getProperty("Filename"); + const std::vector<std::vector<std::string> > values = getProperty("Filename"); std::string outputWsName = getProperty("OutputWorkspace"); + // Generate ws names for the files to be loaded. + const std::vector<std::vector<unsigned int> > runs = multiFileProp->getRuns(); std::vector<std::string> wsNames; - wsNames.resize(allFilenames.size()); + wsNames.resize(values.size()); - std::transform( - allFilenames.begin(), allFilenames.end(), + // If we successfully parsed run numbers (in the cases where we were given a string of "inst[runs].raw") then + // we can use them to generate the ws names. + if( ! runs.empty() ) + { + std::transform( + runs.begin(), runs.end(), + wsNames.begin(), + generateWsNameFromRuns); + } + // Else if no runs were returned then the string we were given was of the form "inst1.raw, inst2.raw, ...". + // It would not make sense to generate ws names from just the run numbers in this case, since we could have + // two files with the same run number with but with different instruments. + else + { + std::transform( + values.begin(), values.end(), wsNames.begin(), generateWsNameFromFileNames); + } - std::vector<API::Workspace_sptr> loadedWsList; + std::vector<std::string> loadedWsNames; - std::vector<std::vector<std::string> >::const_iterator filenames = allFilenames.begin(); - std::vector<std::string >::const_iterator wsName = wsNames.begin(); - assert( allFilenames.size() == wsNames.size() ); + std::vector<std::vector<std::string> >::const_iterator values_it = values.begin(); + std::vector<std::string >::const_iterator wsNames_it = wsNames.begin(); - // Cycle through the filenames and wsNames. - for(; filenames != allFilenames.end(); ++filenames, ++wsName) + // Cycle through the fileNames and wsNames. + for(; values_it != values.end(); ++values_it, ++wsNames_it) { + std::vector<std::string> fileNames = *values_it; + std::string wsName = *wsNames_it; + // If there is only one filename, then just load it to the given wsName. - if(filenames->size() == 1) + if(fileNames.size() == 1) { - Workspace_sptr loadedWs = loadFileToWs(filenames->at(0), *wsName); - loadedWs->setName(*wsName); - loadedWsList.push_back(loadedWs); + loadFileToHiddenWs(fileNames.at(0), wsName); + loadedWsNames.push_back("__" + wsName); } // Else there is more than one filename. Load them all, sum them, and rename the // result to the given wsName. @@ -489,58 +507,67 @@ namespace Mantid { // Load all files and place the resulting workspaces in a vector. std::vector<Workspace_sptr> loadedWs; - std::vector<std::string>::const_iterator filename = filenames->begin(); + std::vector<std::string>::const_iterator vIt = fileNames.begin(); - for(; filename != filenames->end(); ++filename) + for(; vIt != fileNames.end(); ++vIt) { - Workspace_sptr ws = loadFileToWs(*filename, (*filename) + "_temp"); + Workspace_sptr ws = loadFileToHiddenWs(*vIt, (*vIt) + "_temp"); loadedWs.push_back(ws); } // Add all workspaces together, sticking the result in sum. Workspace_sptr sum; - for( size_t i = 1; i < loadedWs.size(); i++ ) + for( + size_t i = 1; // Start at second workspace in list. + i < loadedWs.size(); + i++) { Workspace_sptr firstWsToAdd; // If there have been no workspaces added yet, then the first workspace to add // is the first workspace in the list. if(sum == Workspace_sptr()) - firstWsToAdd = loadedWs[i-1]; + firstWsToAdd = loadedWs.at(i-1); // Else the first workspace to add is "sum" itself. else firstWsToAdd = sum; - Workspace_sptr secondWsToAdd = loadedWs[i]; + Workspace_sptr secondWsToAdd = loadedWs.at(i); sum = plusWs(firstWsToAdd, secondWsToAdd); } - sum->setName(*wsName); + // Delete all of the temporarily loaded workspaces except the first one, so that we are left only + // with sum at this point. + for(size_t i = 1; i < fileNames.size(); i++) + { + deleteWs("__" + fileNames.at(i) + "_temp"); + } - // Add the sum to the list of loaded workspace names. - loadedWsList.push_back(sum); + // Rename the sum and add to the list of loaded workspace names. + renameWs(sum->name(), "__" + wsName); + loadedWsNames.push_back("__" + wsName); } } // If we only have one loaded ws, set it as the output. - if(loadedWsList.size() == 1) + if(loadedWsNames.size() == 1) { - setProperty("OutputWorkspace", loadedWsList[0]); + renameWs(loadedWsNames.at(0), outputWsName); + setProperty("OutputWorkspace", AnalysisDataService::Instance().retrieve(outputWsName.c_str())); } // Else we have multiple loaded workspaces - group them and set the group as output. else { - API::WorkspaceGroup_sptr group = groupWsList(loadedWsList); - setProperty("OutputWorkspace", group); - std::vector<std::string> childWsNames = group->getNames(); - size_t count = 1; - for(auto childWsName = childWsNames.begin(); childWsName != childWsNames.end(); ++childWsName, ++count ) - { - Workspace_sptr childWs = group->getItem(*childWsName); - std::string outWsPropName = "OutputWorkspace_" + boost::lexical_cast<std::string>(count); - - declareProperty(new WorkspaceProperty<Workspace>(outWsPropName, *childWsName, Direction::Output)); - setProperty(outWsPropName, childWs); - } + Mantid::API::IAlgorithm_sptr groupingAlg = this->createSubAlgorithm("GroupWorkspaces",0, 0, true, 1); + groupingAlg->setAlwaysStoreInADS(true); + + groupingAlg->setProperty("InputWorkspaces",loadedWsNames); + groupingAlg->setProperty("OutputWorkspace",outputWsName.c_str()); + groupingAlg->execute(); + + auto outws = AnalysisDataService::Instance().retrieve(outputWsName.c_str()); + unhideWs(outputWsName); + + setProperty("OutputWorkspace", outws); } } @@ -702,20 +729,25 @@ namespace Mantid * * @returns a pointer to the loaded workspace */ - API::Workspace_sptr Load::loadFileToWs( + API::Workspace_sptr Load::loadFileToHiddenWs( const std::string & fileName, const std::string & wsName) { Mantid::API::IAlgorithm_sptr loadAlg = createSubAlgorithm("Load", 1); + // Here, as a workaround for groupworkspaces who's members have names but no + // accompanying entries in the ADS, we set the sub algo to setAlwaysStoreInADS. + //loadAlg->setChild(false); + loadAlg->setAlwaysStoreInADS(true); + // Get the list properties for the concrete loader load algorithm const std::vector<Kernel::Property*> & props = getProperties(); // Loop through and set the properties on the sub algorithm - std::vector<Kernel::Property*>::const_iterator prop = props.begin(); - for (; prop != props.end(); ++prop) + std::vector<Kernel::Property*>::const_iterator itr; + for (itr = props.begin(); itr != props.end(); ++itr) { - const std::string propName = (*prop)->name(); + const std::string propName = (*itr)->name(); if( this->existsProperty(propName) ) { @@ -725,7 +757,7 @@ namespace Mantid } else if(propName == "OutputWorkspace") { - loadAlg->setPropertyValue("OutputWorkspace", wsName); + loadAlg->setPropertyValue("OutputWorkspace","__" + wsName); } else { @@ -736,7 +768,7 @@ namespace Mantid loadAlg->executeAsSubAlg(); - return loadAlg->getProperty("OutputWorkspace"); + return AnalysisDataService::Instance().retrieve("__" + wsName); } /** @@ -752,48 +784,97 @@ namespace Mantid Workspace_sptr ws2) { Mantid::API::IAlgorithm_sptr plusAlg = createSubAlgorithm("Plus", 1); - plusAlg->setProperty("LHSWorkspace", ws1); - plusAlg->setProperty("RHSWorkspace", ws2); - plusAlg->setProperty("OutputWorkspace", ws1); + plusAlg->setPropertyValue("LHSWorkspace", ws1->name()); + plusAlg->setPropertyValue("RHSWorkspace", ws2->name()); + plusAlg->setPropertyValue("OutputWorkspace", ws1->name()); plusAlg->executeAsSubAlg(); return ws1; } /** - * Groups together a vector of workspaces. This is done "manually", since the - * workspaces being passed will be outside of the ADS and so the GroupWorkspaces - * alg is not an option here. + * Renames a workspace. + * + * @param oldName :: the old workspace name. + * @param newName :: the new workspace name. + */ + void Load::renameWs( + const std::string & oldName, + const std::string & newName) + { + if(oldName == newName) + return; + + Mantid::API::IAlgorithm_sptr renameAlg = createSubAlgorithm("RenameWorkspace", 1); + renameAlg->setChild(true); // Must be keep child=true to prevent locking errors + renameAlg->setAlwaysStoreInADS(true); + renameAlg->setPropertyValue("InputWorkspace", oldName); + renameAlg->setPropertyValue("OutputWorkspace", newName); + renameAlg->executeAsSubAlg(); + } + + /** + * Deletes a given workspace. If the given workspace is a group workspace, + * then this function calls itself recursively for each workspace in the group. + * + * @param wsName :: the name of the workspace to delete. + */ + void Load::deleteWs(const std::string & wsName) + { + Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName); + if(WorkspaceGroup_sptr wsGrpSptr = + boost::dynamic_pointer_cast<WorkspaceGroup>(ws)) + { + std::vector<std::string> childWsNames = wsGrpSptr->getNames(); + std::vector<std::string>::iterator vIt = childWsNames.begin(); + + for(; vIt != childWsNames.end(); ++vIt) + { + // Call this function recursively, to delete each child workspace. + deleteWs(*vIt); + } + } + else + { + Mantid::API::IAlgorithm_sptr deleteAlg = createSubAlgorithm("DeleteWorkspace", 1); + + deleteAlg->setPropertyValue("Workspace", wsName); + deleteAlg->execute(); + } + } + + /** + * Unhides a given workspace (by removing the "__" prefix from its name if present). + * If the given workspace is a group workspace, then this function calls itself + * recursively for each workspace in the group. * - * @param wsList :: the list of workspaces to group + * @param wsName :: the name of the workspace to unhide. */ - API::WorkspaceGroup_sptr Load::groupWsList(std::vector<API::Workspace_sptr> wsList) + void Load::unhideWs(const std::string & wsName) { - WorkspaceGroup_sptr group = WorkspaceGroup_sptr(new WorkspaceGroup); + std::set<std::string> adsContents1 = AnalysisDataService::Instance().getObjectNames(); - for( auto ws = wsList.begin(); ws != wsList.end(); ++ws ) + Workspace_sptr ws = AnalysisDataService::Instance().retrieve(wsName); + if(WorkspaceGroup_sptr wsGrpSptr = + boost::dynamic_pointer_cast<WorkspaceGroup>(ws)) { - WorkspaceGroup_sptr isGroup = boost::dynamic_pointer_cast<WorkspaceGroup>(*ws); - // If the ws to add is already a group, then add its children individually. - if(isGroup) + std::vector<std::string> childWsNames = wsGrpSptr->getNames(); + std::vector<std::string>::iterator vIt = childWsNames.begin(); + + for(; vIt != childWsNames.end(); ++vIt) { - std::vector<std::string> childrenNames = isGroup->getNames(); - size_t count = 1; - for( auto childName = childrenNames.begin(); childName != childrenNames.end(); ++childName, ++count) - { - Workspace_sptr childWs = isGroup->getItem(*childName); - isGroup->remove(*childName); - childWs->setName(isGroup->getName() + "_" + boost::lexical_cast<std::string>(count)); - group->addWorkspace(childWs); - } + // Call this function recursively, to unhide each child workspace. + unhideWs(*vIt); } - else + } + else + { + if(boost::starts_with(wsName, "__")) { - group->addWorkspace(*ws); + std::string newName = wsName.substr(2, (wsName.size() - 2)); + renameWs(wsName, newName); } } - - return group; } } // namespace DataHandling diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiFileNameParser.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiFileNameParser.h index f289b1b8b34a8cdb03bd52552d0a595a51f45e17..9d39fb7d2b3979e20949b12386c0f2621e148179 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiFileNameParser.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/MultiFileNameParser.h @@ -55,15 +55,6 @@ namespace Kernel extern const std::string ANY, LIST; } - /** - * Comparator for set that holds instrument names in Parser. - */ - class MANTID_KERNEL_DLL ReverseCaselessCompare - { - public: - bool operator()(const std::string & a, const std::string & b); - }; - /** This class takes a string representing multiple files and parses it into a vector of vectors of file names. Filenames to be added are placed in the @@ -72,13 +63,10 @@ namespace Kernel The string to parse should be of the format [dir][inst][under][runs][ext], where: [dir] (Optional) = The OS-specific file directory, e.g. "c:\data\" - [inst] (Optional) = The instrument name, e.g. "IRS" or "PG3". If none provided then use default. + [inst] (Required) = The instrument name, e.g. "IRS" or "PG3" [under] (Optional) = An underscore. [runs] (Required) = The run numbers, e.g. "0102, 0110-0115, 0120, 0130:0140:2" [ext] (Optional) = The file extension, e.g. ".raw" - - NOTE: This parser does not parse strings of the form: - [dir][inst][under][runs][ext],[dir][inst][under][runs][ext] */ class MANTID_KERNEL_DLL Parser { @@ -122,8 +110,6 @@ namespace Kernel std::string m_dirString, m_instString, m_underscoreString, m_runString, m_extString; /// The instrument-specific run zero padding value. int m_zeroPadding; - /// All the valid instrument names. - std::set<std::string, ReverseCaselessCompare> m_validInstNames; }; /** diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h index 4d54f2e899c1d2adb7b0109de7724be5ac97a697..91b98437dfda6f5862fbd381a8c87fd8adfab703 100644 --- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h +++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/PropertyWithValue.h @@ -72,7 +72,7 @@ std::string toString(const boost::shared_ptr<T>& value) /// Specialisation for a property of type std::vector. template <typename T> -std::string toString(const std::vector<T>& value, const std::string & delimiter = ",") +std::string toString(const std::vector<T>& value) { std::stringstream result; std::size_t vsize = value.size(); @@ -80,15 +80,14 @@ std::string toString(const std::vector<T>& value, const std::string & delimiter { result << value[i]; if (i + 1 != vsize) - result << delimiter; + result << ","; } return result.str(); } /// Specialisation for a property of type std::vector<std::vector>. template <typename T> -std::string toString(const std::vector<std::vector<T> >& value, const std::string & outerDelimiter = ",", - const std::string & innerDelimiter = "+") +std::string toString(const std::vector<std::vector<T> >& value) { std::stringstream result; std::size_t vsize = value.size(); @@ -99,11 +98,11 @@ std::string toString(const std::vector<std::vector<T> >& value, const std::strin { result << value[i][j]; if (j + 1 != innervsize) - result << innerDelimiter; + result << "+"; } if (i + 1 != vsize) - result << outerDelimiter; + result << ","; } return result.str(); } @@ -175,18 +174,18 @@ void toValue(const std::string& strvalue, std::vector<T>& value) } template <typename T> -void toValue(const std::string& strvalue, std::vector<std::vector<T> >& value, const std::string & outerDelimiter = ",", - const std::string & innerDelimiter = "+") +void toValue(const std::string& strvalue, std::vector<std::vector<T> >& value) { + // Split up comma-separated properties typedef Poco::StringTokenizer tokenizer; - tokenizer tokens(strvalue, outerDelimiter, tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM); + tokenizer tokens(strvalue, ",", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM); value.clear(); value.reserve(tokens.count()); for (tokenizer::Iterator oIt = tokens.begin(); oIt != tokens.end(); ++oIt) { - tokenizer values(*oIt, innerDelimiter, tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM); + tokenizer values(*oIt, "+", tokenizer::TOK_IGNORE_EMPTY | tokenizer::TOK_TRIM); std::vector<T> vect; for (tokenizer::Iterator iIt = values.begin(); iIt != values.end(); ++iIt) diff --git a/Code/Mantid/Framework/Kernel/src/MultiFileNameParser.cpp b/Code/Mantid/Framework/Kernel/src/MultiFileNameParser.cpp index f52e5d5408789644ca28712266854a8aef81ebfd..8d56ccf05a4d5c7e9314e7b9dab6615412cdb95a 100644 --- a/Code/Mantid/Framework/Kernel/src/MultiFileNameParser.cpp +++ b/Code/Mantid/Framework/Kernel/src/MultiFileNameParser.cpp @@ -4,7 +4,6 @@ #include "MantidKernel/MultiFileNameParser.h" #include "MantidKernel/ConfigService.h" -#include "MantidKernel/FacilityInfo.h" #include "MantidKernel/InstrumentInfo.h" #include "MantidKernel/Exception.h" @@ -68,7 +67,7 @@ namespace Kernel std::vector<std::vector<unsigned int> > generateRange(unsigned int from, unsigned int to, unsigned int stepSize, bool addRuns); void validateToken(const std::string & token); bool matchesFully(const std::string & stringToMatch, const std::string & regexString); - std::string getMatchingString(const std::string & regexString, const std::string & toParse, bool caseless = false); + std::string getMatchingString(const std::string & regexString, const std::string & toParse); std::string pad(std::string run, unsigned int padLength); std::set< std::pair<unsigned int, unsigned int> > & mergeAdjacentRanges( @@ -161,26 +160,6 @@ namespace Kernel // Return the suggested ws name. return parser.instString() + parser.underscoreString() + toString(runs); } - - ///////////////////////////////////////////////////////////////////////////// - // Comparator class. - ///////////////////////////////////////////////////////////////////////////// - - /** - * Comparator for the set that holds instrument names in Parser. This is reversed - * since we want to come across the longer instrument names first. It is caseless - * so we don't get "inst" coming before "INSTRUMENT" - though this is probably overkill. - */ - bool ReverseCaselessCompare::operator()(const std::string & a, const std::string & b) - { - std::string lowerA(a); - std::string lowerB(b); - - std::transform(lowerA.begin(), lowerA.end(), lowerA.begin(), tolower); - std::transform(lowerB.begin(), lowerB.end(), lowerB.begin(), tolower); - - return lowerA > lowerB; - } ///////////////////////////////////////////////////////////////////////////// // Public member functions of Parser class. @@ -189,27 +168,8 @@ namespace Kernel /// Constructor. Parser::Parser() : m_runs(), m_fileNames(), m_multiFileName(), m_dirString(), m_instString(), - m_underscoreString(), m_runString(), m_extString(), m_zeroPadding(), m_validInstNames() - { - ConfigServiceImpl & config = ConfigService::Instance(); - - std::string supportedFacilities = config.getString("supported.facilities"); - - std::vector<std::string> allFacilityNames; - boost::split( - allFacilityNames, - supportedFacilities, - boost::is_any_of(";")); - - for( auto facilityName = allFacilityNames.begin(); facilityName != allFacilityNames.end(); ++facilityName ) - { - const FacilityInfo & facility = config.getFacility(*facilityName); - const std::vector<InstrumentInfo> instruments = facility.instruments(); - - for( auto instrument = instruments.begin(); instrument != instruments.end(); ++instrument ) - m_validInstNames.insert(instrument->shortName()); - } - } + m_underscoreString(), m_runString(), m_extString(), m_zeroPadding() + {} /// Destructor. Parser::~Parser() @@ -301,48 +261,42 @@ namespace Kernel std::string base = m_multiFileName.substr( m_dirString.size(), m_multiFileName.size() - (m_dirString.size() + m_extString.size())); - if( base.empty() ) - throw std::runtime_error("There does not appear to be any runs present."); + // Get the instrument name using a regex. + m_instString = getMatchingString("^" + Regexs::INST, base); - // If there is only a list of runs, then we need to use the default instrument. - if( matchesFully(base, Regexs::LIST) ) + if(m_instString.empty()) { - m_runString = base; + // Use default instrument name if one is not found. m_instString = ConfigService::Instance().getString("default.instrument"); - // Do the files of the default instrument have an underscore? - InstrumentInfo instInfo = ConfigService::Instance().getInstrument(m_instString); - m_underscoreString = instInfo.delimiter(); + // The run string is now what's left. Throw if nothing found since runs are required. + m_runString = base; + if(m_runString.empty()) + throw std::runtime_error("There does not appear to be any runs present."); } else { - // At this point, if we have a valid and parsable run string, then what remains must be - // one of the available instrument names followed by a possible underscore and a list of runs. - for( auto instName = m_validInstNames.begin(); instName != m_validInstNames.end(); ++instName ) - { - if(matchesFully(base, *instName + ".*")) - { - m_instString = getMatchingString("^" + *instName, base, true); // Caseless. - break; - } - } - - if( m_instString.empty() ) - throw std::runtime_error("There does not appear to be a valid instrument name present."); - // Check for an underscore after the instrument name. - size_t underscore = base.find_last_of("_"); + size_t underscore = base.find_first_of("_"); if(underscore == m_instString.size()) m_underscoreString = "_"; - // We can now deduce the run string. Throw if not found since runs are required. + // We can now deduce the run string. Throw if not found since this runs are required. m_runString = base.substr(m_underscoreString.size() + m_instString.size()); - if(m_runString.empty()) + if(m_instString.empty()) throw std::runtime_error("There does not appear to be any runs present."); } - - InstrumentInfo instInfo = ConfigService::Instance().getInstrument(m_instString); - m_zeroPadding = instInfo.zeroPadding(); + + // Get zero padding of instrument. If throws then instrument does not exist. + try + { + InstrumentInfo instInfo = ConfigService::Instance().getInstrument(m_instString); + m_zeroPadding = instInfo.zeroPadding(); + } + catch (const Exception::NotFoundError &) + { + throw std::runtime_error("There does not appear to be a valid instrument name present."); + } } ///////////////////////////////////////////////////////////////////////////// @@ -686,22 +640,12 @@ namespace Kernel * * @returns the part (if any) of the given string that matches the given regex */ - std::string getMatchingString(const std::string & regexString, const std::string & toParse, bool caseless) + std::string getMatchingString(const std::string & regexString, const std::string & toParse) { - boost::regex regex; - if( caseless ) - { - regex = boost::regex(regexString, boost::regex::icase); - } - else - { - regex = boost::regex(regexString); - } - boost::sregex_iterator it( - toParse.begin(), toParse.end(), - regex - ); + toParse.begin(), toParse.end(), + boost::regex(regexString) + ); if(it == boost::sregex_iterator()) return ""; diff --git a/Code/Mantid/Framework/Kernel/test/MultiFileNameParserTest.h b/Code/Mantid/Framework/Kernel/test/MultiFileNameParserTest.h index 273d72f6fcc29bbbc23025acb53f6ca0ba7689b4..eafaf3a479b0ff3aa93c461a9567b180a72ca7fd 100644 --- a/Code/Mantid/Framework/Kernel/test/MultiFileNameParserTest.h +++ b/Code/Mantid/Framework/Kernel/test/MultiFileNameParserTest.h @@ -185,32 +185,31 @@ public: void test_errorThrownWhenPassedUnexpectedChar() { - std::string message = "Non-numeric or otherwise unaccetable character(s) detected."; TS_ASSERT_THROWS_EQUALS(parseMultiRunString("#"), const std::runtime_error & re, std::string(re.what()), - message); + "Non-numeric or otherwise unaccetable character(s) detected."); TS_ASSERT_THROWS_EQUALS(parseMultiRunString("a"), const std::runtime_error & re, std::string(re.what()), - message); + "Non-numeric or otherwise unaccetable character(s) detected."); TS_ASSERT_THROWS_EQUALS(parseMultiRunString("Z"), const std::runtime_error & re, std::string(re.what()), - message); + "Non-numeric or otherwise unaccetable character(s) detected."); TS_ASSERT_THROWS_EQUALS(parseMultiRunString("("), const std::runtime_error & re, std::string(re.what()), - message); + "Non-numeric or otherwise unaccetable character(s) detected."); TS_ASSERT_THROWS_EQUALS(parseMultiRunString(">"), const std::runtime_error & re, std::string(re.what()), - message); + "Non-numeric or otherwise unaccetable character(s) detected."); TS_ASSERT_THROWS_EQUALS(parseMultiRunString("1012-n1059:5"), const std::runtime_error & re, std::string(re.what()), - message); + "Non-numeric or otherwise unaccetable character(s) detected."); } void test_errorThrownOnEmptyToken() diff --git a/Code/Mantid/Framework/Properties/Mantid.properties.template b/Code/Mantid/Framework/Properties/Mantid.properties.template index ff4a30776180e3e62cbca1045a60eed00f237431..9c15e54f743db5fe9bdb8658fd3595ec1ccc6bb5 100644 --- a/Code/Mantid/Framework/Properties/Mantid.properties.template +++ b/Code/Mantid/Framework/Properties/Mantid.properties.template @@ -180,8 +180,3 @@ filefinder.casesensitive=Off # Control which geometry the Instrument View window displays, valid values # are "Default", "Neutronic" or "Physical". instrument.view.geometry=Default - -# Disabling multifile loading will allow users to load files with "," or "+" -# in their path, but at the cost of no longer being able to load multiple -# files with a single call to Load. -loading.multifile=On diff --git a/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/LoadDialog.h b/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/LoadDialog.h index e4daa4398c76639d7ee055cfd3db18fdfc844f40..ba26fe763484a5e5ed76f6a38815c4b4904c7cae 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/LoadDialog.h +++ b/Code/Mantid/MantidQt/CustomDialogs/inc/MantidQtCustomDialogs/LoadDialog.h @@ -99,7 +99,7 @@ namespace MantidQt /// Form Ui::LoadDialog m_form; /// The current file - QString m_currentFiles; + QString m_currentFile; /// The initial height int m_initialHeight; }; diff --git a/Code/Mantid/MantidQt/CustomDialogs/src/LoadDialog.cpp b/Code/Mantid/MantidQt/CustomDialogs/src/LoadDialog.cpp index dde6c7e8be05bf723dd704e3527c1a6a13357646..2f7676c0be8b2b71b4d90f13203a43a37b35f34f 100644 --- a/Code/Mantid/MantidQt/CustomDialogs/src/LoadDialog.cpp +++ b/Code/Mantid/MantidQt/CustomDialogs/src/LoadDialog.cpp @@ -32,7 +32,7 @@ namespace MantidQt /// Default constructor LoadDialog:: LoadDialog(QWidget *parent) - : API::AlgorithmDialog(parent), m_form(), m_currentFiles(), m_initialHeight(0) + : API::AlgorithmDialog(parent), m_form(), m_currentFile(), m_initialHeight(0) { } @@ -96,7 +96,7 @@ namespace MantidQt std::string errMess = getAlgorithm()->getPointerToProperty("Filename")->isValid(); if ( !errMess.empty() ) { - m_currentFiles = ""; + m_currentFile = ""; createDynamicWidgets(); return; } @@ -135,7 +135,7 @@ namespace MantidQt AlgorithmDialog::saveInput(); //Ensure the filename is store as the full file API::AlgorithmInputHistory::Instance().storeNewValue("Load", - QPair<QString, QString>("Filename", m_currentFiles)); + QPair<QString, QString>("Filename", m_currentFile)); } /** @@ -199,13 +199,13 @@ namespace MantidQt if( !m_form.fileWidget->isValid() ) return; // First step is the get the specific loader that is responsible IAlgorithm *loadAlg = getAlgorithm(); - const QString filenames = m_form.fileWidget->getText(); - if( filenames == m_currentFiles ) return; - m_currentFiles = filenames; + const QString filename = m_form.fileWidget->getFirstFilename(); + if( filename == m_currentFile ) return; + m_currentFile = filename; removeOldInputWidgets(m_form.propertyLayout); // The new file might be invalid try { - loadAlg->setPropertyValue("Filename", filenames.toStdString()); + loadAlg->setPropertyValue("Filename", filename.toStdString()); } catch(std::exception & exc) { diff --git a/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp b/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp index 8002aaba68f4777ab479b6641ac970c6353b7f5e..f410c27b14f2fbe382fa761caf27b663aabb3caf 100644 --- a/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp +++ b/Code/Mantid/MantidQt/MantidWidgets/src/MWRunFiles.cpp @@ -134,8 +134,8 @@ void FindFilesThread::run() } /** - * Create a list of files from the given algorithm property. - */ +* Create a list of file extensions from the given algorithm property. +*/ void FindFilesThread::getFilesFromAlgorithm() { Mantid::API::IAlgorithm_sptr algorithm = Mantid::API::AlgorithmManager::Instance().createUnmanaged(m_algorithm.toStdString());