Newer
Older
Gigg, Martyn Anthony
committed
//-----------------------------------------------------------------
// Includes
//-----------------------------------------------------------------
#include "MantidKernel/FileProperty.h"
#include "MantidKernel/FileValidator.h"
Gigg, Martyn Anthony
committed
#include "MantidKernel/ConfigService.h"
#include "Poco/Path.h"
#include "Poco/File.h"
Gigg, Martyn Anthony
committed
using namespace Mantid::Kernel;
//-----------------------------------------------------------------
// Public member functions
//-----------------------------------------------------------------
/**
* Constructor
* @param name The name of the property
Gigg, Martyn Anthony
committed
* @param default_value A default value for the property
* @param exts The set of allowed extensions
* @param action An enum indicating whether this should be a load/save property
* @param direction An optional direction (default=Input)
Gigg, Martyn Anthony
committed
*/
FileProperty::FileProperty(const std::string & name, const std::string& default_value, unsigned int action,
const std::vector<std::string> & exts, unsigned int direction)
Gigg, Martyn Anthony
committed
: PropertyWithValue<std::string>(name, default_value, new FileValidator(exts, (action > FileProperty::NoExistLoad) ), direction),
Gigg, Martyn Anthony
committed
m_action(action)
{
}
/**
* Check if this is a load property
* @returns True if the property is a Load property and false if a Save type
*/
bool FileProperty::isLoadProperty() const
{
Gigg, Martyn Anthony
committed
return (m_action != FileProperty::Save);
Gigg, Martyn Anthony
committed
/**
* Set the filename
* @param filename The value here is treated as a filename.
* @returns A string indicating the outcome of the attempt to set the property. An empty string indicates success.
*/
std::string FileProperty::setValue(const std::string & filename)
{
// If the path is absolute then don't do any searching
Gigg, Martyn Anthony
committed
if( Poco::Path(filename).isAbsolute() )
Gigg, Martyn Anthony
committed
{
return PropertyWithValue<std::string>::setValue(filename);
}
std::string valid_string("");
// For relative paths, differentiate between load and save types
Gigg, Martyn Anthony
committed
if( isLoadProperty() )
Gigg, Martyn Anthony
committed
{
Gigg, Martyn Anthony
committed
if( filename.empty() ) return PropertyWithValue<std::string>::setValue(filename);
Gigg, Martyn Anthony
committed
Poco::File relative(filename);
Poco::File check_file(Poco::Path(Poco::Path::current()).resolve(relative.path()));
Gigg, Martyn Anthony
committed
valid_string = PropertyWithValue<std::string>::setValue(check_file.path());
if( !valid_string.empty() )
Gigg, Martyn Anthony
committed
{
const std::vector<std::string>& search_dirs = ConfigService::Instance().getDataSearchDirs();
std::vector<std::string>::const_iterator iend = search_dirs.end();
for( std::vector<std::string>::const_iterator it = search_dirs.begin(); it != iend; ++it )
{
check_file = Poco::File(Poco::Path(*it).resolve(relative.path()));
if( check_file.exists() )
{
valid_string = PropertyWithValue<std::string>::setValue(check_file.path());
break;
}
}
}
}
else
{
Gigg, Martyn Anthony
committed
if( filename.empty() ) return "Empty filename not allowed.";
Gigg, Martyn Anthony
committed
// We have a relative save path so just prepend the path that is in the 'defaultsave.directory'
Gigg, Martyn Anthony
committed
// Note that this catches the Poco::NotFoundException and returns an empty string in that case
Gigg, Martyn Anthony
committed
std::string save_path = ConfigService::Instance().getString("defaultsave.directory");
Poco::Path save_dir;
if( save_path.empty() )
{
save_dir = Poco::Path(filename).parent();
Gigg, Martyn Anthony
committed
// If we only have a stem filename, parent() will make save_dir empty and then Poco::File throws
if( save_dir.toString().empty() )
{
save_dir = Poco::Path::current();
}
Gigg, Martyn Anthony
committed
}
else
{
save_dir = Poco::Path(save_path).makeDirectory();
}
if( Poco::File(save_dir).canWrite() )
{
Gigg, Martyn Anthony
committed
std::string fullpath = save_dir.resolve(filename).toString();
// Check if the fullpath exists
Poco::Path stempath(fullpath);
stempath.makeParent();
if( !stempath.toString().empty() )
{
//Relative directory - Check it exists
Poco::File stem(stempath);
if( !stem.exists() )
{
stem.createDirectory();
}
}
valid_string = PropertyWithValue<std::string>::setValue(fullpath);
Gigg, Martyn Anthony
committed
}
else
{
valid_string = "Cannot write file to path \"" + save_dir.toString() + "\". Location is not writable.";
}
}
return valid_string;
}