Skip to content

Commit

Permalink
Pass command line arguments to script in MantidPlot
Browse files Browse the repository at this point in the history
In the case where MantidPlot acts in place of a standard script
interpreter then set any extra arguments after the filename as
sys arguments in the scripting environment, e.g. sys.argv in Python.
Refs #9639
  • Loading branch information
martyngigg committed Aug 12, 2014
1 parent 841555c commit 84cf682
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 24 deletions.
49 changes: 34 additions & 15 deletions Code/Mantid/MantidPlot/src/ApplicationWindow.cpp
Expand Up @@ -14702,18 +14702,18 @@ void ApplicationWindow::parseCommandLineArguments(const QStringList& args)
return;
}

bool exec(false), quit(false), default_settings(false),
unknown_opt_found(false);
QString file_name;
QString str;
bool exec = false;
bool quit = false;
bool default_settings = false;
int filename_argindex, counter(0);
foreach(str, args) {
if( (str == "-v" || str == "--version") ||
(str == "-r" || str == "--revision") ||
(str == "-a" || str == "--about") ||
(str == "-h" || str == "--help") )
{
QMessageBox::critical(this, tr("MantidPlot - Error"),//Mantid
tr("<b> %1 </b>: This command line option must be used without other arguments!").arg(str));
g_log.warning() << str.ascii() << ": This command line option must be used without other arguments!";
}
else if( (str == "-d" || str == "--default-settings"))
{
Expand All @@ -14728,24 +14728,36 @@ void ApplicationWindow::parseCommandLineArguments(const QStringList& args)
{
exec = true;
quit = true;
// Minimize ourselves
this->showMinimized();
}
else if (str.startsWith("-") || str.startsWith("--"))
// if filename not found yet then these are all program arguments so we should
// know what they all are
else if (file_name.isEmpty() && (str.startsWith("-") || str.startsWith("--")))
{
QMessageBox::critical(this, tr("MantidPlot - Error"),//Mantid
tr("<b> %1 </b> unknown command line option!").arg(str) + "\n" + tr("Type %1 to see the list of the valid options.").arg("'MantidPlot -h'"));
g_log.warning() << "'" << str.ascii() << "' unknown command line option!\n"
<< "Type 'MantidPlot -h'' to see the list of the valid options.";
unknown_opt_found = true;
break;
}
else
{
// First option that doesn't start "-" is considered a filename and the rest arguments to that file
if(file_name.isEmpty())
{
file_name = str;
filename_argindex = counter;
}
}
++counter;
}

QString file_name = args[num_args-1]; // last argument
if(file_name.startsWith("-")){// no file name given
if(unknown_opt_found || file_name.isEmpty())
{// no file name given
initWindow();
savedProject();
return;
}

if (!file_name.isEmpty()){
else
{
QFileInfo fi(file_name);
if (fi.isDir()){
QMessageBox::critical(this, tr("MantidPlot - Error opening file"),//Mantid
Expand All @@ -14764,10 +14776,17 @@ void ApplicationWindow::parseCommandLineArguments(const QStringList& args)
workingDir = fi.dirPath(true);
saveSettings();//the recent projects must be saved

QStringList cmdArgs = args;
cmdArgs.erase(cmdArgs.begin(), cmdArgs.begin() + filename_argindex);
// Set as arguments in script environment
scriptingEnv()->setSysArgs(cmdArgs);

if (exec)
{
if(quit)
{
// Minimize ourselves
this->showMinimized();
try
{
executeScriptFile(file_name, Script::Asynchronous);
Expand Down Expand Up @@ -16450,7 +16469,7 @@ ApplicationWindow * ApplicationWindow::loadScript(const QString& fn, bool existi
* Runs a script from a file. Mainly useful for automatically running scripts
* @param filename The full path to the file
* @param execMode How should the script be executed. If asynchronous
* this method waits on the thread finishing
* this method waits on the thread finishing
*/
void ApplicationWindow::executeScriptFile(const QString & filename, const Script::ExecutionMode execMode)
{
Expand Down
34 changes: 33 additions & 1 deletion Code/Mantid/MantidPlot/src/PythonScripting.cpp
Expand Up @@ -90,6 +90,20 @@ PythonScripting::~PythonScripting()
{
}

/**
* @param args A list of strings that denoting command line arguments
*/
void PythonScripting::setSysArgs(const QStringList &args)
{
GlobalInterpreterLock gil;

PyObject *argv = toPyList(args);
if(argv && m_sys)
{
PyDict_SetItemString(m_sys, "argv", argv);
}
}

/**
* Create a new script object that can execute code within this environment
*
Expand Down Expand Up @@ -271,13 +285,31 @@ QStringList PythonScripting::toStringList(PyObject *py_seq)
PyObject *item = PyList_GetItem(py_seq, i);
if( PyString_Check(item) )
{
elements << PyString_AsString(item);
elements << PyString_AsString(item);
}
}
}
return elements;
}

/**
* Returns a new Python list from the given Qt QStringList
* @param items A reference to a QStringList object
* @return A new reference to a Python list. Caller is responsible for calling Py_DECREF
*/
PyObject *PythonScripting::toPyList(const QStringList &items)
{
Py_ssize_t length = static_cast<Py_ssize_t>(items.length());
PyObject * pylist = PyList_New((length));
for(Py_ssize_t i = 0; i < length; ++i)
{
QString item = items.at(static_cast<int>(i));
PyList_SetItem(pylist, i,
PyString_FromString(item.ascii()));
}
return pylist;
}

/**
* Returns an integer representation of the object as a c long. No check is performed to see if it is an integer
* @param object :: A PyInt_Type instance
Expand Down
7 changes: 6 additions & 1 deletion Code/Mantid/MantidPlot/src/PythonScripting.h
Expand Up @@ -57,6 +57,9 @@ class PythonScripting: public ScriptingEnv
/// 'Fake' method needed for IPython import
void set_parent(PyObject*) {}

/// Set the argv attribute on the sys module
void setSysArgs(const QStringList & args);

/// Create a new script object that can execute code within this enviroment
virtual Script *newScript(const QString &name, QObject * context, const Script::InteractionType interact) const;

Expand All @@ -69,8 +72,10 @@ class PythonScripting: public ScriptingEnv

/// Return a string represenation of the given object
QString toString(PyObject *object, bool decref = false);
//Convert a Python list object to a Qt QStringList
/// Convert a Python list object to a Qt QStringList
QStringList toStringList(PyObject *py_seq);
/// Convert a QtringList to a Python List
PyObject * toPyList(const QStringList & items);
/// Returns an integer representation of the object. No check is performed to see if it is an integer
long toLong(PyObject *object, bool decref = false);

Expand Down
7 changes: 4 additions & 3 deletions Code/Mantid/MantidPlot/src/ScriptingEnv.h
Expand Up @@ -63,8 +63,9 @@ class ScriptingEnv : public QObject

/// Is the environment initialized
bool isInitialized() const { return d_initialized; }
/// Query if any code is currently being executed
//bool isRunning() const { return m_is_running; }

/// If the environment supports it, set the system arguments
virtual void setSysArgs(const QStringList & args) = 0;

/// Create a script object that is responsible for executing actual code
virtual Script *newScript(const QString &name, QObject * context, const Script::InteractionType interact) const = 0;
Expand All @@ -76,7 +77,7 @@ class ScriptingEnv : public QObject
/// Return a documentation string for the given mathematical function.
virtual const QString mathFunctionDoc(const QString&) const { return QString::null; }
/// Return a list of file extensions commonly used for this language.
virtual const QStringList fileExtensions() const { return QStringList(); };
virtual const QStringList fileExtensions() const { return QStringList(); }
/// Construct a filter expression from fileExtension(), suitable for QFileDialog.
const QString fileFilter() const;
/// Return the name of the scripting language supported by this environment
Expand Down
5 changes: 5 additions & 0 deletions Code/Mantid/MantidPlot/src/muParserScripting.cpp
Expand Up @@ -89,6 +89,11 @@ const muParserScripting::mathFunction muParserScripting::math_functions[] = {
{0,0,NULL,NULL,NULL,0}
};

void muParserScripting::setSysArgs(const QStringList &)
{
throw std::runtime_error("muParserScripting does not support command line arguments");
}

const QStringList muParserScripting::mathFunctions() const
{
QStringList l;
Expand Down
11 changes: 7 additions & 4 deletions Code/Mantid/MantidPlot/src/muParserScripting.h
Expand Up @@ -52,10 +52,13 @@ class muParserScripting: public ScriptingEnv
muParserScripting(ApplicationWindow *parent) : ScriptingEnv(parent, langName) { d_initialized=true; }
static ScriptingEnv *constructor(ApplicationWindow *parent) { return new muParserScripting(parent); }

Script *newScript(const QString &name, QObject * context, const Script::InteractionType) const
{
return new muParserScript(const_cast<muParserScripting*>(this), name, context);
}
/// Set the system arguments. Throws an exception as it is not supported
void setSysArgs(const QStringList & args);

Script *newScript(const QString &name, QObject * context, const Script::InteractionType) const
{
return new muParserScript(const_cast<muParserScripting*>(this), name, context);
}

virtual bool supportsEvaluation() { return true; }

Expand Down

0 comments on commit 84cf682

Please sign in to comment.