diff --git a/scribus/plugins/scriptplugin/scriptercore.cpp b/scribus/plugins/scriptplugin/scriptercore.cpp index 3903617809..cf41110b9f 100644 --- a/scribus/plugins/scriptplugin/scriptercore.cpp +++ b/scribus/plugins/scriptplugin/scriptercore.cpp @@ -9,6 +9,7 @@ for which a new license (GPL+exception) is in place. #include #include #include +#include #include #include #include @@ -37,7 +38,7 @@ for which a new license (GPL+exception) is in place. #include "prefscontext.h" #include "prefstable.h" #include "prefsmanager.h" -#include "scribusapp.h" // need it to acces ScQApp->pythonScript +#include "scribusapp.h" // need it to acces ScQApp->pythonScript & ScQApp->pythonScriptArgs ScripterCore::ScripterCore(QWidget* parent) { @@ -227,6 +228,12 @@ void ScripterCore::RecentScript(QString fn) } void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter) +{ + slotRunScriptFile(fileName, QStringList(), inMainInterpreter); +} + +void ScripterCore::slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter) +/** run "filename" python script with the additional arguments provided in "arguments" */ { // Prevent two scripts to be run concurrently or face crash! if (ScCore->primaryMainWindow()->scriptIsRunning()) @@ -252,16 +259,27 @@ void ScripterCore::slotRunScriptFile(QString fileName, bool inMainInterpreter) // Init the scripter module in the sub-interpreter initscribus(ScCore->primaryMainWindow()); } + // Make sure sys.argv[0] is the path to the script - char* comm[2]; - comm[0] = na.data(); + arguments.prepend(na.data()); + // and tell the script if it's running in the main intepreter or // a subinterpreter using the second argument, ie sys.argv[1] if (inMainInterpreter) - comm[1] = const_cast("ext"); + arguments.insert(1,QString("ext")); else - comm[1] = const_cast("sub"); - PySys_SetArgv(2, comm); + arguments.insert(1,QString("sub")); + + //convert arguments (QListString) to char** for Python bridge + /* typically arguments == ['path/to/script.py','ext','--argument1','valueforarg1','--flag']*/ + char *comm[arguments.size()]; + for (int i = 0; i < arguments.size(); i++) + { + comm[i] = new char[arguments.at(i).toLocal8Bit().size()+1]; //+1 to allow adding '\0'. may be useless, don't know how to check. + strcpy(comm[i],arguments.at(i).toLocal8Bit().data()+'\0'); + } + PySys_SetArgv(arguments.size(), comm); + // call python script PyObject* m = PyImport_AddModule((char*)"__main__"); if (m == NULL) @@ -357,7 +375,7 @@ void ScripterCore::slotRunPythonScript() { if (!ScQApp->pythonScript.isNull()) { - slotRunScriptFile(ScQApp->pythonScript, true); + slotRunScriptFile(ScQApp->pythonScript, ScQApp->pythonScriptArgs, true); FinishScriptRun(); } } diff --git a/scribus/plugins/scriptplugin/scriptercore.h b/scribus/plugins/scriptplugin/scriptercore.h index 1e929f4706..72e546141e 100644 --- a/scribus/plugins/scriptplugin/scriptercore.h +++ b/scribus/plugins/scriptplugin/scriptercore.h @@ -39,8 +39,9 @@ public slots: void StdScript(QString filebasename); void RecentScript(QString fn); void slotRunScriptFile(QString fileName, bool inMainInterpreter = false); + void slotRunScriptFile(QString fileName, QStringList arguments, bool inMainInterpreter = false); void slotRunPythonScript(); // needed for running python script from CLI - void slotRunScript(const QString Script); + void slotRunScript(const QString script); void slotInteractiveScript(bool); void slotExecute(); /*! \brief Show docstring of the script to the user. diff --git a/scribus/scribusapp.cpp b/scribus/scribusapp.cpp index fec40559ad..a1f4c52c2c 100644 --- a/scribus/scribusapp.cpp +++ b/scribus/scribusapp.cpp @@ -32,6 +32,7 @@ for which a new license (GPL+exception) is in place. #include #include #include +#include #include #include #include @@ -71,6 +72,8 @@ for which a new license (GPL+exception) is in place. #define ARG_UPGRADECHECK "--upgradecheck" #define ARG_TESTS "--tests" #define ARG_PYTHONSCRIPT "--python-script" +#define ARG_SCRIPTARG "--python-arg" +#define CMD_OPTIONS_END "--" #define ARG_VERSION_SHORT "-v" #define ARG_HELP_SHORT "-h" @@ -86,6 +89,7 @@ for which a new license (GPL+exception) is in place. #define ARG_UPGRADECHECK_SHORT "-u" #define ARG_TESTS_SHORT "-T" #define ARG_PYTHONSCRIPT_SHORT "-py" +#define ARG_SCRIPTARG_SHORT "-pa" // Qt wants -display not --display or -d #define ARG_DISPLAY_QT "-display" @@ -108,6 +112,7 @@ ScribusQApp::ScribusQApp( int & argc, char ** argv ) : QApplication(argc, argv), m_scDLMgr = 0; m_ScCore = NULL; initDLMgr(); + } ScribusQApp::~ScribusQApp() @@ -151,18 +156,36 @@ void ScribusQApp::parseCommandLine() int testargsc; #endif showFontInfo=false; - showProfileInfo=false; + showProfileInfo=false; + bool neversplash = false; - //Parse for command line information options, and lang + //Parse for command line options // Qt5 port: do this in a Qt compatible manner QStringList args = arguments(); int argsc = args.count(); - for(int i = 1; i < argsc; i++) - { - arg = args[i]; - if ((arg == ARG_LANG || arg == ARG_LANG_SHORT) && (++i < argsc)) { - lang = args[i]; + //Init translations + initLang(); + + useGUI = true; + int argi = 1; + for( ; argi < argsc; argi++) { //handle options (not positional parameters) + arg = args[argi]; + + if (arg == ARG_SCRIPTARG || arg == ARG_SCRIPTARG_SHORT) { //needs to be first to give precedence to script argument name over scribus' options + if (++argi [value]").arg(arg).toLocal8Bit().data() << std::endl; + showUsage(); + std::exit(EXIT_FAILURE); + } + if (++argi so we discard the // last argument. FIXME: Qt only understands -display not --display and -d , we need to work // around this. } else if (arg == ARG_PREFS || arg == ARG_PREFS_SHORT) { - prefsUserFile = QFile::decodeName(args[i + 1].toLocal8Bit()); + prefsUserFile = QFile::decodeName(args[argi + 1].toLocal8Bit()); if (!QFileInfo(prefsUserFile).exists()) { - showHeader(); - if (prefsUserFile.left(1) == "-" || prefsUserFile.left(2) == "--") { - std::cout << tr("Invalid argument: ").toLocal8Bit().data() << prefsUserFile.toLocal8Bit().data() << std::endl; - } else { - std::cout << tr("File %1 does not exist, aborting.").arg(prefsUserFile).toLocal8Bit().data() << std::endl; - } - showUsage(); + showError(prefsUserFile); std::exit(EXIT_FAILURE); } else { - ++i; + ++argi; } } else if (strncmp(arg.toLocal8Bit().data(),"-psn_",4) == 0) { // Andreas Vox: Qt/Mac has -psn_blah flags that must be accepted. } else if (arg == ARG_PYTHONSCRIPT || arg == ARG_PYTHONSCRIPT_SHORT) { - pythonScript = QFile::decodeName(args[i + 1].toLocal8Bit()); + pythonScript = QFile::decodeName(args[argi + 1].toLocal8Bit()); if (!QFileInfo(pythonScript).exists()) { - showHeader(); - if (pythonScript.left(1) == "-" || pythonScript.left(2) == "--") { - std::cout << tr("Invalid argument: ").toLocal8Bit().data() << pythonScript.toLocal8Bit().data() << std::endl; - } else { - std::cout << tr("File %1 does not exist, aborting.").arg(pythonScript).toLocal8Bit().data() << std::endl; - } - showUsage(); + showError(pythonScript); std::exit(EXIT_FAILURE); } else { - ++i; + ++argi; } + } else if (arg == CMD_OPTIONS_END) { //double dash, indicates end of command line options, see http://unix.stackexchange.com/questions/11376/what-does-double-dash-mean-also-known-as-bare-double-dash + argi++; + break; + } else { //argument is not a known option, but either positional parameter or invalid. + break; + } + } + // parse for remaining (positional) arguments, if any + for ( ; argi").arg(ARG_PYTHONSCRIPT).arg(tr("filename"))), tr("Run filename in Python scripter") ); + printArgLine(ts, ARG_SCRIPTARG_SHORT, qPrintable(QString("%1 <%2> [%3]").arg(ARG_SCRIPTARG).arg(tr("argument")).arg(tr("value"))), tr("Argument passed on to python script, with an optional value, no effect without -py") ); printArgLine(ts, ARG_NOGUI_SHORT, ARG_NOGUI, tr("Do not start GUI") ); + ts << (QString(" %1").arg(CMD_OPTIONS_END,-39)) << tr("Explicit end of command line options"); endl(ts); + #if defined(_WIN32) && !defined(_CONSOLE) printArgLine(ts, ARG_CONSOLE_SHORT, ARG_CONSOLE, tr("Display a console window") ); @@ -558,6 +574,18 @@ void ScribusQApp::showHeader() endl(ts); } +void ScribusQApp::showError(QString arg) +{ + showHeader(); + if (arg.left(1) == "-" || arg.left(2) == "--") { + std::cout << tr("Invalid argument: %1").arg(arg).toLocal8Bit().data() << std::endl; + } else { + std::cout << tr("File %1 does not exist, aborting.").arg(arg).toLocal8Bit().data() << std::endl; + } + showUsage(); + std::cout << tr("Scribus Version").toLocal8Bit().data() << " " << VERSION << std::endl; +} + void ScribusQApp::neverSplash(bool splashOff) { QString prefsDir = ScPaths::getApplicationDataDir(); diff --git a/scribus/scribusapp.h b/scribus/scribusapp.h index 2857306d75..0add48f719 100644 --- a/scribus/scribusapp.h +++ b/scribus/scribusapp.h @@ -23,6 +23,7 @@ for which a new license (GPL+exception) is in place. #define SCRIBUSAPP_H #include #include +#include #include "scribusapi.h" @@ -71,10 +72,12 @@ class SCRIBUS_API ScribusQApp : public QApplication const QString& currGUILanguage() { return GUILang; } ScDLManager* dlManager() { return m_scDLMgr; } QString pythonScript; // script to be run in python from CLI + QStringList pythonScriptArgs; // command line arguments and flags for script from CLI private: ScribusCore* m_ScCore; void showHeader(); + void showError(QString arg); void showVersion(); /*! \author Franz Schmid