diff --git a/Code/Mantid/MantidPlot/CMakeLists.txt b/Code/Mantid/MantidPlot/CMakeLists.txt index 8195878f55aa36f349321ff13d4f98e076e86ed0..579a47f0ddb063e1c48c8f968d7842f4452b4b29 100644 --- a/Code/Mantid/MantidPlot/CMakeLists.txt +++ b/Code/Mantid/MantidPlot/CMakeLists.txt @@ -810,6 +810,11 @@ add_custom_command ( TARGET MantidPlot POST_BUILD ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/ipython_plugin ) +########################################################################### +# Documentation targets +########################################################################### +add_subdirectory( docs ) + ########################################################################### # MantidPlot Python Unit Tests ########################################################################### diff --git a/Code/Mantid/MantidPlot/docs/CMakeLists.txt b/Code/Mantid/MantidPlot/docs/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f14056d397c99b18cca3db17ff33573bd25c618f --- /dev/null +++ b/Code/Mantid/MantidPlot/docs/CMakeLists.txt @@ -0,0 +1,4 @@ +########################################################################### +# Add each directory +########################################################################### +add_subdirectory( python ) diff --git a/Code/Mantid/MantidPlot/docs/python/CMakeLists.txt b/Code/Mantid/MantidPlot/docs/python/CMakeLists.txt index 203801a22be84951d17719633dc2e7db13466152..97f439486007aefc5fef70c15afca42181325b66 100644 --- a/Code/Mantid/MantidPlot/docs/python/CMakeLists.txt +++ b/Code/Mantid/MantidPlot/docs/python/CMakeLists.txt @@ -6,30 +6,41 @@ find_package ( Sphinx ) if ( SPHINX_FOUND ) - # Fill in the config file and autogen file - configure_file ( conf.py.in conf.py @ONLY ) + # Fill in the config file and autogen file with build information + configure_file ( source/conf.py.in source/conf.py @ONLY ) configure_file ( autogen_api.py.in autogen_api.py @ONLY ) - - # These files need to be relative to the conf.py file - add_custom_command ( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/index.rst - COMMAND ${CMAKE_COMMAND} ARGS -E copy - ${CMAKE_CURRENT_SOURCE_DIR}/index.rst ${CMAKE_CURRENT_BINARY_DIR}/index.rst - COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/api ${CMAKE_CURRENT_BINARY_DIR}/api - COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/_static ${CMAKE_CURRENT_BINARY_DIR}/_static - COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/_templates ${CMAKE_CURRENT_BINARY_DIR}/_templates - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/conf.py + configure_file ( runsphinx.py.in runsphinx.py @ONLY ) + + # Sphinx seems to require the config file to be next to the rest of the source + # files meaning we need to copy everything over to the build directory + set ( SPHINX_SOURCE + source/index.rst + source/api/mantid.rst + source/api/mantidplot.rst + source/_templates/indexcontent.html + source/_templates/indexsidebar.html + source/_templates/layout.html ) + + # The destination for the copied files + set ( SPHINX_CONF_DIR ${CMAKE_CURRENT_BINARY_DIR} ) + set ( SPHINX_CONF_FILES ) + foreach( file ${SPHINX_SOURCE} ) + set ( out_file ${SPHINX_CONF_DIR}/${file} ) + add_custom_command ( OUTPUT ${out_file} + COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/${file} ${out_file} + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${file} + ) + set ( SPHINX_CONF_FILES ${SPHINX_CONF_FILES} ${out_file} ) + endforeach() + set ( SPHINX_HTML_BUILD ${CMAKE_CURRENT_BINARY_DIR}/../../../python-sphinx/html ) # Sphinx is run as '${SPHINX_EXECUTABLE} -b sourcedir builddir' - set ( OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/../../../python-sphinx/html ) add_custom_target ( python-sphinx - COMMAND python autogen_api.py - COMMAND ${SPHINX_EXECUTABLE} -b html ${CMAKE_CURRENT_BINARY_DIR} ${OUTPUT_DIR} - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/index.rst + COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/MantidPlot -xq autogen_api.py + COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/MantidPlot -xq runsphinx.py + DEPENDS ${SPHINX_CONF_FILES} COMMENT "Build Python Sphinx API documentation" - ) + ) endif () diff --git a/Code/Mantid/MantidPlot/docs/python/autogen_api.py.in b/Code/Mantid/MantidPlot/docs/python/autogen_api.py.in index fdb134dfe36bf70c17daf26b55329050de08f6d7..5a7857910f28bcba64231bf757dce42adabf86c1 100755 --- a/Code/Mantid/MantidPlot/docs/python/autogen_api.py.in +++ b/Code/Mantid/MantidPlot/docs/python/autogen_api.py.in @@ -5,9 +5,8 @@ import sys import os import inspect -# Append the path to the mantid library +# Append the path to the mantid/mantidplot library sys.path.append("@CMAKE_RUNTIME_OUTPUT_DIRECTORY@") -import mantid #------------------------------------------------------------------------------ @@ -27,7 +26,6 @@ class ClassAPIWriter(object): :inherited-members: """ - def __init__(self, cls, outputdir, extension): if not inspect.isclass(cls): raise TypeError("Expected class type, found %s" % str(type(cls))) @@ -41,6 +39,11 @@ class ClassAPIWriter(object): # FQL name could contain '_cmodule' aswell, strip this off modname = self._cls.__module__ + + # Hack for replaceing qti reference with mantidplot ref + if 'qti' in modname: + modname = modname.replace('_qti','mantidplot') + # Build up the module name and don't reference the "private" modules pieces = modname.split('.') fqlmod = '' for p in pieces: @@ -55,26 +58,89 @@ class ClassAPIWriter(object): def filename(self): return self._filename + +class FunctionAPIWriter(object): + """Writes a Sphinx documentation file + for a given function + """ + + _doc_template = \ +"""%(title)s +%(underline)s -if __name__ == '__main__': - extension = '.rst' - apidir = os.path.join(os.path.dirname(__file__), 'api') - output_dir = os.path.join(apidir,'generated') - if not os.path.exists(output_dir): - os.mkdir(output_dir) +.. module:`%(modulename)s` + +.. autofunction:: %(modulename)s.%(function)s + +""" + + def __init__(self, func, outputdir, extension): + if not inspect.isfunction(func): + raise TypeError("Expected function type, found %s" % str(type(cls))) + self._filename = os.path.join(outputdir, func.__name__ + extension) + self._func = func + + def write(self): + rstfile = open(self._filename, 'w') + funcname = self._func.__name__ + underline = '='*len(funcname) # Sphinx doesn't like the title underline being incorrect + # FQL name could contain '_cmodule' aswell, strip this off + modname = self._func.__module__ + # Hack for replaceing qti reference with mantidplot ref + if 'qti' in modname: + modname = modname.replace('_qti','mantidplot') + + # Write the file + rstfile.write(self._doc_template % {'title':funcname, 'underline':underline,\ + 'modulename':modname,'function':funcname}) + rstfile.close() + + def filename(self): + return self._filename + + +def generate_api_doc(module, indexfilename): + """Write the sphinx doc files for a given module + + @param module - The module object + @param indexfilename - A file that will contain an index list of the given files + """ - indexfilename = os.path.join(apidir, 'autogen.txt') indexfile = open(indexfilename, 'w') indexfile.write(".. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n") indexfile.write(".. toctree::\n\n") - print "Generating API docs" - for name, member in inspect.getmembers(mantid): + print "Generating %s API docs" % module.__name__ + for name, member in inspect.getmembers(module): + if name.startswith("_"): continue if inspect.isclass(member): apiwriter = ClassAPIWriter(member, output_dir, extension) + elif inspect.isfunction(member): + apiwriter = FunctionAPIWriter(member, output_dir, extension) else: continue apiwriter.write() indexfile.write(" generated/" + os.path.basename(apiwriter.filename()) + "\n") indexfile.close() - print "Completed autogenerating API docs" + print "Done generating API %s docs" % module.__name__ + +if __name__ == '__main__': + extension = '.rst' + apidir = os.path.join(os.path.dirname(__file__), 'source','api') + output_dir = os.path.join(apidir,'generated') + if not os.path.exists(output_dir): + os.mkdir(output_dir) + + import mantid + indexfilename = os.path.join(apidir, 'automantid.txt') + generate_api_doc(mantid, indexfilename) + try: + import mantidplot + indexfilename = os.path.join(apidir, 'automantidplot.txt') + generate_api_doc(mantidplot, indexfilename) + except: + import warnings + warnings.warn("Unable to import mantidplot. No api documentation will be generated for MantidPlot") + + + diff --git a/Code/Mantid/MantidPlot/docs/python/runsphinx.py.in b/Code/Mantid/MantidPlot/docs/python/runsphinx.py.in new file mode 100644 index 0000000000000000000000000000000000000000..228a0545d8d3033b226a0386fa905af77a244640 --- /dev/null +++ b/Code/Mantid/MantidPlot/docs/python/runsphinx.py.in @@ -0,0 +1,21 @@ +"""We need to run Sphinx inside MantidPlot to document the internal + module. This script calls the sphinx entry point with the necessary + arguments +""" + +__requires__ = 'Sphinx==1.1.2' +import sys +import os +from pkg_resources import load_entry_point + +mantidplot = "@CMAKE_RUNTIME_OUTPUT_DIRECTORY@/MantidPlot" +builder = "html" +src_dir = "@CMAKE_CURRENT_BINARY_DIR@/source" +output_dir = "@CMAKE_CURRENT_BINARY_DIR@/../../../python-sphinx/" + builder +argv = [mantidplot,'-b', builder, src_dir, output_dir] + +if __name__ == '__main__': + sys.exit( + load_entry_point('Sphinx==1.1.2', 'console_scripts', 'sphinx-build')(argv) + ) + diff --git a/Code/Mantid/MantidPlot/docs/python/source/_static/Mantid.png b/Code/Mantid/MantidPlot/docs/python/source/_static/Mantid.png new file mode 100644 index 0000000000000000000000000000000000000000..4423c49d05e87efedd4c75432e0aaae44d84b01c Binary files /dev/null and b/Code/Mantid/MantidPlot/docs/python/source/_static/Mantid.png differ diff --git a/Code/Mantid/MantidPlot/docs/python/source/_static/Mantid_Logo_Transparent.png b/Code/Mantid/MantidPlot/docs/python/source/_static/Mantid_Logo_Transparent.png new file mode 100644 index 0000000000000000000000000000000000000000..247578ebf7aded4b1ea8ff48ab198cfb4224c1c8 Binary files /dev/null and b/Code/Mantid/MantidPlot/docs/python/source/_static/Mantid_Logo_Transparent.png differ diff --git a/Code/Mantid/MantidPlot/docs/python/source/_templates/indexcontent.html b/Code/Mantid/MantidPlot/docs/python/source/_templates/indexcontent.html new file mode 100644 index 0000000000000000000000000000000000000000..f2322b6fd654dd02978a8ec3f8149cff2337946b --- /dev/null +++ b/Code/Mantid/MantidPlot/docs/python/source/_templates/indexcontent.html @@ -0,0 +1,45 @@ +{% extends "defindex.html" %} +{% block tables %} + + <p><strong>Contents:</strong></p> + <table class="contentstable" align="center"><tr> + <td width="50%"> + <p class="biglink"><a class="biglink" href="http://www.mantidproject.org/Python_in_Mantid_Training">Introductary training</a><br/> + <span class="linkdescr">An introduction to Python in Mantid</span></p> + </td><td width="50%"> + <p class="biglink"><a class="biglink" href="{{ pathto("api/mantid") }}">Mantid Framework Reference</a><br/> + <span class="linkdescr">Documents the classes and functions of the Mantid framework</span></p> + <p class="biglink"><a class="biglink" href="{{ pathto("api/mantidplot") }}">MantidPlot Reference</a><br/> + <span class="linkdescr">Documents the classes and functions of MantidPlot</span></p> + </td></tr> + </table> + + <p><strong>Indices and tables:</strong></p> + <table class="contentstable" align="center"><tr> + <td width="50%"> + <p class="biglink"><a class="biglink" href="{{ pathto("py-modindex") }}">Module Index</a><br/> + <span class="linkdescr">quick access to all modules</span></p> + <p class="biglink"><a class="biglink" href="{{ pathto("genindex") }}">General Index</a><br/> + <span class="linkdescr">all functions, classes, terms</span></p> + <p class="biglink"><a class="biglink" href="{{ pathto("glossary") }}">Glossary</a><br/> + <span class="linkdescr">the most important terms explained</span></p> + </td><td width="50%"> + <p class="biglink"><a class="biglink" href="{{ pathto("search") }}">Search page</a><br/> + <span class="linkdescr">search this documentation</span></p> + <p class="biglink"><a class="biglink" href="{{ pathto("contents") }}">Complete Table of Contents</a><br/> + <span class="linkdescr">lists all sections and subsections</span></p> + </td></tr> + </table> + + <p><strong>Useful links:</strong></p> + <table class="contentstable" align="center"><tr> + <td width="50%"> + <p class="biglink"><a class="biglink" href="http://www.mantidproject.org" }}">Mantid project wiki</a><br/> + <span class="linkdescr">Mantid wiki</span></p> + </td><td width="50%"> + <p class="biglink"><a class="biglink" href="http://docs.scipy.org/doc/numpy-1.5.x/user/" }}">Numpy Tutorial</a><br/> + <span class="linkdescr">An introduction to numpy</span></p> + </td></tr> + </table> + +{% endblock %} diff --git a/Code/Mantid/MantidPlot/docs/python/source/_templates/indexsidebar.html b/Code/Mantid/MantidPlot/docs/python/source/_templates/indexsidebar.html new file mode 100644 index 0000000000000000000000000000000000000000..309b5904044b5a57d60a73d1d27edccdb0749a96 --- /dev/null +++ b/Code/Mantid/MantidPlot/docs/python/source/_templates/indexsidebar.html @@ -0,0 +1,6 @@ + <h3>Resources</h3> + <ul> + <li><a href="http://www.mantidproject.org/">Mantid wiki</a></li> + <li> </li> + <li><a href="http://docs.python.org/">Python manual</a></li> + </ul> diff --git a/Code/Mantid/MantidPlot/docs/python/source/_templates/layout.html b/Code/Mantid/MantidPlot/docs/python/source/_templates/layout.html new file mode 100644 index 0000000000000000000000000000000000000000..6240cc9016f391dacf5fc35610bfa5832d747447 --- /dev/null +++ b/Code/Mantid/MantidPlot/docs/python/source/_templates/layout.html @@ -0,0 +1,10 @@ +{% extends "default/layout.html" %} + +{%- block sidebarlogo %} +{%- if logo %} + <p class="logo"><a href="{{ pathto(master_doc) }}"> + <img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo" width=220 height=110/> + </a></p> +{%- endif %} +{%- endblock %} + diff --git a/Code/Mantid/MantidPlot/docs/python/source/api/mantid.rst b/Code/Mantid/MantidPlot/docs/python/source/api/mantid.rst index 9c5886d1e2bc13387ee089f3b9619ba202886b81..0d8ad2910ee66d2a9f4fd631e41353dbb3d3b4ed 100644 --- a/Code/Mantid/MantidPlot/docs/python/source/api/mantid.rst +++ b/Code/Mantid/MantidPlot/docs/python/source/api/mantid.rst @@ -1,13 +1,9 @@ .. _mantid: -################################# - Mantid Python Class Reference -################################# +################################## + Mantid Framework class reference +################################## .. module:: mantid -Some lovely wording here... - -and probably more structure - -.. include:: autogen.txt +.. include:: automantid.txt diff --git a/Code/Mantid/MantidPlot/docs/python/source/api/mantidplot.rst b/Code/Mantid/MantidPlot/docs/python/source/api/mantidplot.rst new file mode 100644 index 0000000000000000000000000000000000000000..65d22abaf5b4bd5b885640bff69b932873786577 --- /dev/null +++ b/Code/Mantid/MantidPlot/docs/python/source/api/mantidplot.rst @@ -0,0 +1,9 @@ +.. _mantidplot: + +########################## + MantidPlot API reference +########################## + +.. module:: mantidplot + +.. include:: automantidplot.txt diff --git a/Code/Mantid/MantidPlot/docs/python/source/conf.py.in b/Code/Mantid/MantidPlot/docs/python/source/conf.py.in index a3d52ad8d12e92470e732da10e9bdae7e8d4093f..b88a2f3af52677ce527d2d39c7aa2bed226730d6 100644 --- a/Code/Mantid/MantidPlot/docs/python/source/conf.py.in +++ b/Code/Mantid/MantidPlot/docs/python/source/conf.py.in @@ -107,14 +107,15 @@ html_theme = 'default' # The name for this set of Sphinx documents. If None, it defaults to # "<project> v<release> documentation". -#html_title = None +html_title = "%s v%s Python Manual" % ("Mantid", version) # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None + +html_logo = os.path.relpath('@CMAKE_HOME_DIRECTORY@/Images/Mantid_Logo_Transparent.png') # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -135,11 +136,15 @@ html_static_path = ['_static'] #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +html_sidebars = { + 'index':'indexsidebar.html' +} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {} +html_additional_pages = { + 'index':'indexcontent.html' +} # If false, no module index is generated. #html_domain_indices = True @@ -168,7 +173,7 @@ html_use_index = True #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'Mantiddoc' +htmlhelp_basename = 'mantid' # -- Options for LaTeX output -------------------------------------------------- diff --git a/Code/Mantid/MantidPlot/docs/python/source/index.rst b/Code/Mantid/MantidPlot/docs/python/source/index.rst index 03da8571917fddc9c4799c2d6346a6453d1189d5..4b858d036e5684870055de55eeddb6a13f33fbb6 100644 --- a/Code/Mantid/MantidPlot/docs/python/source/index.rst +++ b/Code/Mantid/MantidPlot/docs/python/source/index.rst @@ -16,6 +16,7 @@ Contents :maxdepth: 1 api/mantid.rst + api/mantidplot.rst Indices and tables ================== diff --git a/Code/Mantid/MantidPlot/mantidplot.py b/Code/Mantid/MantidPlot/mantidplot.py index 0ca9973f9a16a3e711da7807f320c72ad05d9d09..0177ed9f7a020b1082f863e27df9859494203cf7 100644 --- a/Code/Mantid/MantidPlot/mantidplot.py +++ b/Code/Mantid/MantidPlot/mantidplot.py @@ -21,7 +21,7 @@ from _qti import PlotSymbol, ImageSymbol, ArrowMarker, ImageMarker #-------------------------- Mantid Python access functions---------------- # Grab a few Mantid things so that we can recognise workspace variables # While we have 2 APIs we need to figure out which to use so add a little bit of indirection -def get_analysis_data_service(): +def _get_analysis_data_service(): """Returns an object that can be used to get a workspace by name from Mantid Returns: @@ -44,7 +44,7 @@ def workspace(name): Args: name: The name of the workspace in the Analysis Data Service. """ - return get_analysis_data_service()[name] + return _get_analysis_data_service()[name] def table(name): """Get a handle on a table. @@ -217,8 +217,7 @@ def stemPlot(source, index, power=None, startPoint=None, endPoint=None): Args: source: A reference to a workspace or a table. index: For a table, the column number or name. For a workspace, the workspace index. - power: The stem unit as a power of 10. If not provided, a dialog will appear with a - suggested value. + power: The stem unit as a power of 10. If not provided, a dialog will appear with a suggested value. startPoint: The first point (row or bin) to use (Default: the first one). endPoint: The last point (row or bin) to use (Default: the last one). @@ -457,26 +456,17 @@ def plotSlice(source, label="", xydim=None, slicepoint=None, Optional Keyword Args: label :: label for the window title - xydim :: indexes or names of the dimensions to plot, - as an (X,Y) list or tuple. - See SliceViewer::setXYDim() - slicepoint :: list with the slice point in each dimension. Must be the - same length as the number of dimensions of the workspace. - See SliceViewer::setSlicePoint() - colormin :: value of the minimum color in the scale - See SliceViewer::setColorScaleMin() - colormax :: value of the maximum color in the scale - See SliceViewer::setColorScaleMax() - colorscalelog :: value of the maximum color in the scale - See SliceViewer::setColorScaleLog() - limits :: list with the (xleft, xright, ybottom, ytop) limits - to the view to show. - See SliceViewer::setXYLimits() + xydim :: indexes or names of the dimensions to plot, as an (X,Y) list or tuple. See SliceViewer::setXYDim() + slicepoint :: list with the slice point in each dimension. Must be the same length as the number of dimensions of the workspace. See SliceViewer::setSlicePoint() + colormin :: value of the minimum color in the scale. See SliceViewer::setColorScaleMin() + colormax :: value of the maximum color in the scale. See SliceViewer::setColorScaleMax() + colorscalelog :: value of the maximum color in the scale. See SliceViewer::setColorScaleLog() + limits :: list with the (xleft, xright, ybottom, ytop) limits to the view to show. See SliceViewer::setXYLimits() Returns: a (list of) handle(s) to the SliceViewerWindow widgets that were open. - Use SliceViewerWindow.getSlicer() to get access to the functions of the - SliceViewer, e.g. setting the view and slice point. + Use SliceViewerWindow.getSlicer() to get access to the functions of the + SliceViewer, e.g. setting the view and slice point. """ workspace_names = __getWorkspaceNames(source) try: @@ -563,10 +553,6 @@ Layer.Right = _qti.GraphOptions.Right Layer.Bottom = _qti.GraphOptions.Bottom Layer.Top = _qti.GraphOptions.Top - - - - #----------------------------------------------------------------------------- #--------------------------- "Private" functions ----------------------------- #----------------------------------------------------------------------------- @@ -604,7 +590,7 @@ def __getWorkspaceNames(source): else: ws_names.append(wspace.getName()) elif isinstance(source,str): - w = get_analysis_data_service()[source] + w = _get_analysis_data_service()[source] if w != None: names = __getWorkspaceNames(w) for n in names: diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp index f74e11d1f661ebb55322b4b3d2d83e5c6f92c12f..8e85e4513d436668d5ccf1aaadcb9da8c1e5d638 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.cpp @@ -10008,7 +10008,7 @@ void ApplicationWindow::addFunctionCurve() Graph* g = plot->activeGraph(); if ( g ) { - FunctionDialog* fd = functionDialog(g); + functionDialog(g); } } @@ -14445,6 +14445,8 @@ void ApplicationWindow::parseCommandLineArguments(const QStringList& args) { exec = true; quit = true; + // Minimize ourselves + this->showMinimized(); } else if (str.startsWith("-") || str.startsWith("--")) { @@ -15935,13 +15937,20 @@ void ApplicationWindow::goToColumn() } } -void ApplicationWindow::showScriptWindow(bool forceVisible) +/** + * Show the script window, creating it if necessary + * @param forceVisible - If true the window is forced to visible rather than toggling + * @param quitting - If true then it is assumed MantidPlot will exit automatically so stdout redirect + * from scripts is disabled. + */ +void ApplicationWindow::showScriptWindow(bool forceVisible, bool quitting) { if( !scriptingWindow ) { // MG 09/02/2010 : Removed parent from scripting window. If it has one then it doesn't respect the always on top // flag, it is treated as a sub window of its parent - scriptingWindow = new ScriptingWindow(scriptingEnv(), NULL); + const bool capturePrint = !quitting; + scriptingWindow = new ScriptingWindow(scriptingEnv(),capturePrint, NULL); scriptingWindow->setObjectName("ScriptingWindow"); scriptingWindow->setAttribute(Qt::WA_DeleteOnClose, false); connect(scriptingWindow, SIGNAL(closeMe()), this, SLOT(saveScriptWindowGeometry())); @@ -15954,7 +15963,14 @@ void ApplicationWindow::showScriptWindow(bool forceVisible) { scriptingWindow->resize(d_script_win_size); scriptingWindow->move(d_script_win_pos); - scriptingWindow->show(); + if( quitting ) + { + scriptingWindow->showMinimized(); + } + else + { + scriptingWindow->show(); + } scriptingWindow->setFocus(); } else @@ -16121,7 +16137,7 @@ ApplicationWindow * ApplicationWindow::loadScript(const QString& fn, bool execut QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); setScriptingLanguage("Python"); restoreApplicationGeometry(); - showScriptWindow(); + showScriptWindow(false, quit); scriptingWindow->open(fn, false); QApplication::restoreOverrideCursor(); if (execute) diff --git a/Code/Mantid/MantidPlot/src/ApplicationWindow.h b/Code/Mantid/MantidPlot/src/ApplicationWindow.h index 66c1d722f84b7c5d9828d2f97b711693c29248cc..67270d924aa4334207e9f91720d7f10dcfeb5e6c 100644 --- a/Code/Mantid/MantidPlot/src/ApplicationWindow.h +++ b/Code/Mantid/MantidPlot/src/ApplicationWindow.h @@ -728,7 +728,7 @@ public slots: //! Connected to the context menu signal from lv; it's called when there are no items selected in the list void showListViewPopupMenu(const QPoint &p); - void showScriptWindow(bool forceVisible = false); + void showScriptWindow(bool forceVisible = false, bool quitting = false); void saveScriptWindowGeometry(); void showScriptInterpreter(); bool testForIPython(); diff --git a/Code/Mantid/MantidPlot/src/PythonScript.cpp b/Code/Mantid/MantidPlot/src/PythonScript.cpp index 86ab6dc7ff655f312d415c996ede0fd3c2332477..36613b596f5ed4310714bf17e6519d599af4b126 100644 --- a/Code/Mantid/MantidPlot/src/PythonScript.cpp +++ b/Code/Mantid/MantidPlot/src/PythonScript.cpp @@ -96,6 +96,12 @@ PythonScript::PythonScript(PythonScripting *env, const QString &code, QObject *c GILHolder gil; PyObject *pymodule = PyImport_AddModule("__main__"); localDict = PyDict_Copy(PyModule_GetDict(pymodule)); + if( QFileInfo(Name).exists() ) + { + QString scriptPath = QFileInfo(Name).absoluteFilePath(); + // Make sure the __file__ variable is set + PyDict_SetItem(localDict,PyString_FromString("__file__"), PyString_FromString(scriptPath.toAscii().data())); + } setQObject(Context, "self"); updatePath(Name, true); @@ -675,6 +681,7 @@ void PythonScript::beginStdoutRedirect() */ void PythonScript::endStdoutRedirect() { + GILHolder gil; // Aqcuire the GIL PyDict_SetItemString(env()->sysDict(), "stdout", stdoutSave); Py_XDECREF(stdoutSave); diff --git a/Code/Mantid/MantidPlot/src/PythonScripting.cpp b/Code/Mantid/MantidPlot/src/PythonScripting.cpp index b81ab36990609df2ae18e30a740ce2c3d826f099..a34667d66c8ce9a30215168226acbab12b57f92a 100644 --- a/Code/Mantid/MantidPlot/src/PythonScripting.cpp +++ b/Code/Mantid/MantidPlot/src/PythonScripting.cpp @@ -184,7 +184,6 @@ bool PythonScripting::start() //Get the refresh protection flag Mantid::Kernel::ConfigService::Instance().getValue("pythonalgorithms.refresh.allowed", refresh_allowed); - if( loadInitFile(mantidbin.absoluteFilePath("mantidplotrc.py")) ) { d_initialized = true; @@ -193,18 +192,22 @@ bool PythonScripting::start() { d_initialized = false; } - return d_initialized; } catch(std::exception & ex) { std::cerr << "Exception in PythonScripting.cpp: " << ex.what() << std::endl; - return false; + d_initialized = false; } catch(...) { std::cerr << "Exception in PythonScripting.cpp" << std::endl; - return false; + d_initialized = false; } + // Reset the stdout/err printers + PyDict_SetItemString(m_sys, "stdout",PyDict_GetItemString(m_sys, "__stdout__")); + PyDict_SetItemString(m_sys, "stderr",PyDict_GetItemString(m_sys, "__stderr__")); + + return d_initialized; } /** diff --git a/Code/Mantid/MantidPlot/src/ScriptManagerWidget.cpp b/Code/Mantid/MantidPlot/src/ScriptManagerWidget.cpp index 051c9635e1d350e8ef5b94f1e9f0d350a26c661d..b4722275e3f10be34181ec2d48413fea2473a399 100644 --- a/Code/Mantid/MantidPlot/src/ScriptManagerWidget.cpp +++ b/Code/Mantid/MantidPlot/src/ScriptManagerWidget.cpp @@ -40,10 +40,10 @@ /** * Constructor */ -ScriptManagerWidget::ScriptManagerWidget(ScriptingEnv *env, QWidget *parent, bool interpreter_mode) +ScriptManagerWidget::ScriptManagerWidget(ScriptingEnv *env, QWidget *parent, bool interpreter_mode, bool capturePrint) : QTabWidget(parent), Scripted(env), m_last_dir(""), m_script_runners(), m_cursor_pos(), m_findrep_dlg(NULL), - m_interpreter_mode(interpreter_mode) + m_interpreter_mode(interpreter_mode), m_recentScriptList(), m_capturePrint(capturePrint) { //Create actions for this widget initActions(); @@ -1062,11 +1062,18 @@ void ScriptManagerWidget::open(bool newtab, const QString & filename) Script * ScriptManagerWidget::createScriptRunner(ScriptEditor *editor) { Script *script = scriptingEnv()->newScript("", this, editor->fileName(), true, - m_toggle_progress->isChecked()); - // Connect the signals that print output and error messages to the formatting functions - connect(script, SIGNAL(print(const QString &)), this, SLOT(displayOutput(const QString &))); - connect(script, SIGNAL(error(const QString &, const QString&, int)), this, - SLOT(displayError(const QString &))); + m_toggle_progress->isChecked()); + if( m_capturePrint ) + { + // Connect the signals that print output and error messages to the formatting functions + connect(script, SIGNAL(print(const QString &)), this, SLOT(displayOutput(const QString &))); + connect(script, SIGNAL(error(const QString &, const QString&, int)), this, + SLOT(displayError(const QString &))); + } + else + { + script->redirectStdOut(false); + } if( editor ) { connect(script, SIGNAL(keywordsChanged(const QStringList&)), editor, diff --git a/Code/Mantid/MantidPlot/src/ScriptManagerWidget.h b/Code/Mantid/MantidPlot/src/ScriptManagerWidget.h index d03912a6695f971328682c96b3b9165e2d7e618d..8f1409f9d1a03dabd70079660475ecee9c4b11f1 100644 --- a/Code/Mantid/MantidPlot/src/ScriptManagerWidget.h +++ b/Code/Mantid/MantidPlot/src/ScriptManagerWidget.h @@ -62,7 +62,7 @@ class ScriptManagerWidget : public QTabWidget, Scripted public: /// Constructor - ScriptManagerWidget(ScriptingEnv *env, QWidget *parent, bool interpreter_mode = false); + ScriptManagerWidget(ScriptingEnv *env, QWidget *parent, bool interpreter_mode = false, bool capturePrint = true); ///Destructor ~ScriptManagerWidget(); ///Save settings applicable to the manager @@ -244,6 +244,8 @@ private: bool m_interpreter_mode; ///list storing the recent scripts QStringList m_recentScriptList; + /// Flag to indicate whether stdout should be redirected + bool m_capturePrint; /// enum used for maximum of recent scripts size enum {MaxRecentScripts = 5}; }; @@ -314,7 +316,6 @@ private: /// If a find is in progress bool m_find_inprogress; - }; diff --git a/Code/Mantid/MantidPlot/src/ScriptingWindow.cpp b/Code/Mantid/MantidPlot/src/ScriptingWindow.cpp index bab4640a463961950eb1dc8fa4f2ecc9afc4d233..3fec164e2f09a2e467913004fbd53df51d8c1ac0 100755 --- a/Code/Mantid/MantidPlot/src/ScriptingWindow.cpp +++ b/Code/Mantid/MantidPlot/src/ScriptingWindow.cpp @@ -257,12 +257,13 @@ void ScriptOutputDock::resetFont() * @param parent :: The parent widget * @param flags :: Window flags passed to the base class */ -ScriptingWindow::ScriptingWindow(ScriptingEnv *env,QWidget *parent, Qt::WindowFlags flags) : +ScriptingWindow::ScriptingWindow(ScriptingEnv *env, bool capturePrint, QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags), m_acceptClose(false) { setObjectName("MantidScriptWindow"); // Sub-widgets - m_manager = new ScriptManagerWidget(env, this); + const bool interpreterMode(false); + m_manager = new ScriptManagerWidget(env, this, interpreterMode, capturePrint); setCentralWidget(m_manager); m_output_dock = new ScriptOutputDock(QString(), m_manager, this); m_output_dock->setScriptIsRunning(false); @@ -279,7 +280,7 @@ ScriptingWindow::ScriptingWindow(ScriptingEnv *env,QWidget *parent, Qt::WindowFl QSettings settings; settings.beginGroup("/ScriptWindow"); QString lastdir = settings.value("LastDirectoryVisited", "").toString(); - // If nothgin, set the last directory to the Mantid scripts directory (if present) + // If nothing, set the last directory to the Mantid scripts directory (if present) if( lastdir.isEmpty() ) { lastdir = QString::fromStdString(Mantid::Kernel::ConfigService::Instance().getString("pythonscripts.directory")); diff --git a/Code/Mantid/MantidPlot/src/ScriptingWindow.h b/Code/Mantid/MantidPlot/src/ScriptingWindow.h index 4856996a4428c6117c469adf83b14521fbdd29f3..454279341aba33ced79ec47381cea7d202a405b7 100755 --- a/Code/Mantid/MantidPlot/src/ScriptingWindow.h +++ b/Code/Mantid/MantidPlot/src/ScriptingWindow.h @@ -107,13 +107,13 @@ class ScriptingWindow : public QMainWindow public: ///Constructor - ScriptingWindow(ScriptingEnv *env,QWidget *parent = 0, Qt::WindowFlags flags = 0); + ScriptingWindow(ScriptingEnv *env,bool capturePrint = true,QWidget *parent = 0, Qt::WindowFlags flags = 0); ///Destructor ~ScriptingWindow(); /// Override the closeEvent void closeEvent(QCloseEvent *event); /// Override the showEvent - void showEvent(QShowEvent *event); + void showEvent(QShowEvent *event); /// Is a script running? bool isScriptRunning() const; ///Save the current state of the script window for next time @@ -177,7 +177,6 @@ private: QAction *m_scripting_lang; /// Flag to define whether we should accept a close event bool m_acceptClose; - }; #endif //SCRIPTINGWINDOW_H_