diff --git a/Framework/API/inc/MantidAPI/Algorithm.h b/Framework/API/inc/MantidAPI/Algorithm.h index faae3348a666d201aaa39ab2c05482d7c246c5a9..6fd4d6441f3f30c7bb9a83c09c61b99be72380c5 100644 --- a/Framework/API/inc/MantidAPI/Algorithm.h +++ b/Framework/API/inc/MantidAPI/Algorithm.h @@ -200,6 +200,11 @@ public: /// is provided const std::string alias() const override { return ""; } + /// function to return URL for algorithm documentation; A default + /// implementation is provided. + /// Override if the algorithm is not part of the Mantid distribution. + const std::string helpURL() const override { return ""; } + const std::string workspaceMethodName() const override; const std::vector<std::string> workspaceMethodOn() const override; const std::string workspaceMethodInputProperty() const override; diff --git a/Framework/API/inc/MantidAPI/AlgorithmProxy.h b/Framework/API/inc/MantidAPI/AlgorithmProxy.h index 827d16e14545becd538ade8fc773eb9575565c9a..23e2d3350ac1b497a1596c46c5370e9e7e61162c 100644 --- a/Framework/API/inc/MantidAPI/AlgorithmProxy.h +++ b/Framework/API/inc/MantidAPI/AlgorithmProxy.h @@ -86,6 +86,8 @@ public: } /// Aliases to the algorithm const std::string alias() const override { return m_alias; } + /// Optional documentation URL for the real algorithm + const std::string helpURL() const override { return m_helpURL; } /// function returns a summary message that will be displayed in the default /// GUI, and in the help. const std::string summary() const override { return m_summary; } @@ -176,6 +178,7 @@ private: const std::string m_categorySeparator; ///< category seperator of the real algorithm const std::string m_alias; ///< alias to the algorithm + const std::string m_helpURL; ///< Optional documentation URL const std::string m_summary; ///<Message to display in GUI and help. const int m_version; ///< version of the real algorithm diff --git a/Framework/API/inc/MantidAPI/IAlgorithm.h b/Framework/API/inc/MantidAPI/IAlgorithm.h index 071e13f90f7377e98841c7a2011049e3ec43b29a..d22b7e91ac615efd7f397139af69d74c32d07803 100644 --- a/Framework/API/inc/MantidAPI/IAlgorithm.h +++ b/Framework/API/inc/MantidAPI/IAlgorithm.h @@ -80,6 +80,10 @@ public: /// function to return any aliases of the algorithm. virtual const std::string alias() const = 0; + /// function to return an optional URL for documentation. + /// Override if the algorithm is not part of the Mantid distribution + virtual const std::string helpURL() const = 0; + /** @name Algorithms As Methods */ ///@{ /// Returns a name that will be used when attached as a workspace method. diff --git a/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h b/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h index 32c0f58fa80185cb77f9ab509bded35360cac58c..54c2f6efa879e5d089691408fd1706a4e6e5d92c 100644 --- a/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h +++ b/Framework/PythonInterface/inc/MantidPythonInterface/api/PythonAlgorithm/AlgorithmAdapter.h @@ -59,6 +59,8 @@ public: const std::string summary() const override; /// Returns a category of the algorithm. const std::string category() const override; + /// Returns optional documentation URL of the algorithm + const std::string helpURL() const override; /// Allow the isRunning method to be overridden bool isRunning() const override; /// Allow the cancel method to be overridden diff --git a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp index cc92119a4c67aa89fc64093d332f1f88962e56f5..889e326b37407529948cd91e19f6da1a88b608af 100644 --- a/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp +++ b/Framework/PythonInterface/mantid/api/src/Exports/IAlgorithm.cpp @@ -346,6 +346,8 @@ void export_ialgorithm() { "Returns the list of categories this algorithm belongs to") .def("summary", &IAlgorithm::summary, arg("self"), "Returns a summary message describing the algorithm") + .def("helpURL", &IAlgorithm::helpURL, arg("self"), + "Returns optional URL for algorithm documentation") .def("workspaceMethodName", &IAlgorithm::workspaceMethodName, arg("self"), "Returns a name that will be used when attached as a workspace " "method. Empty string indicates do not attach") diff --git a/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp b/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp index 8a110298ee50ea2d56958080a07ca3b397d204f1..515d5c2052a7a5bfdb6caad6bf8e508e99b6dffd 100644 --- a/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp +++ b/Framework/PythonInterface/mantid/api/src/PythonAlgorithm/AlgorithmAdapter.cpp @@ -103,9 +103,21 @@ const std::string AlgorithmAdapter<BaseAlgorithm>::summary() const { } /** - * @return True if the algorithm is considered to be running + * Optional documentation URL of the algorithm, empty string if not overridden. */ template <typename BaseAlgorithm> +const std::string AlgorithmAdapter<BaseAlgorithm>::helpURL() const { + try { + return callMethod<std::string>(getSelf(), "helpURL"); + } catch (UndefinedAttributeError &) { + return std::string(); + } +} + +/** +*@return True if the algorithm is considered to be running +*/ +template <typename BaseAlgorithm> bool AlgorithmAdapter<BaseAlgorithm>::isRunning() const { if (!m_isRunningObj) { return SuperClass::isRunning(); diff --git a/Framework/PythonInterface/test/python/mantid/api/AlgorithmManagerTest.py b/Framework/PythonInterface/test/python/mantid/api/AlgorithmManagerTest.py index 9eababd3b7bda1f98bd8a127e54a36ba6176475b..5f5823d63a87f405503cfaf61cb8dcc1049c64de 100644 --- a/Framework/PythonInterface/test/python/mantid/api/AlgorithmManagerTest.py +++ b/Framework/PythonInterface/test/python/mantid/api/AlgorithmManagerTest.py @@ -15,6 +15,7 @@ class AlgorithmManagerTest(unittest.TestCase): self.assertEquals(alg.name(), "ConvertUnits") self.assertEquals(alg.version(), 1) self.assertEquals(alg.category(), "Transforms\\Units") + self.assertEquals(alg.helpURL(), "") def test_create_unknown_alg_throws(self): self.assertRaises(RuntimeError, AlgorithmManager.create,"DoesNotExist") diff --git a/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py b/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py index 96e223076e53debf067f23b498f28cf25a164cb9..e93b83e27edb3d123e5d575c5fba3a25e8aad784 100644 --- a/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py +++ b/Framework/PythonInterface/test/python/mantid/api/AlgorithmTest.py @@ -21,6 +21,7 @@ class AlgorithmTest(unittest.TestCase): self.assertEquals('DataHandling', self._load.category()) self.assertEquals(1, len(self._load.categories())) self.assertEquals('DataHandling', self._load.categories()[0]) + self.assertEquals('', self._load.helpURL()) def test_get_unknown_property_raises_error(self): self.assertRaises(RuntimeError, self._load.getProperty, "NotAProperty") diff --git a/Framework/PythonInterface/test/python/mantid/api/PythonAlgorithmTraitsTest.py b/Framework/PythonInterface/test/python/mantid/api/PythonAlgorithmTraitsTest.py index 23d67225cf8cab8d0ccc0c4ded6eb0925232d7a5..bbbf4a8895ffffb87378dbc36a61a914428de1d9 100644 --- a/Framework/PythonInterface/test/python/mantid/api/PythonAlgorithmTraitsTest.py +++ b/Framework/PythonInterface/test/python/mantid/api/PythonAlgorithmTraitsTest.py @@ -28,6 +28,9 @@ class TestPyAlgOverriddenAttrs(PythonAlgorithm): def category(self): return "BestAlgorithms" + def helpURL(self): + return "Optional documentation URL" + def isRunning(self): return True @@ -106,6 +109,7 @@ class PythonAlgorithmTest(unittest.TestCase): self.assertEquals(alg.name(), "TestPyAlgOverriddenAttrs") self.assertEquals(alg.version(), 2) self.assertEquals(alg.category(), "BestAlgorithms") + self.assertEquals(alg.helpURL(), "Optional documentation URL") def test_alg_can_be_cancelled(self): alg = AlgorithmManager.createUnmanaged("CancellableAlg") diff --git a/MantidQt/MantidWidgets/src/MantidHelpWindow.cpp b/MantidQt/MantidWidgets/src/MantidHelpWindow.cpp index c8613668120d3695ad8d108a03516bd3427093d8..281babbed39e8b7b1ed5013750aa2a5a5760b7d4 100644 --- a/MantidQt/MantidWidgets/src/MantidHelpWindow.cpp +++ b/MantidQt/MantidWidgets/src/MantidHelpWindow.cpp @@ -1,3 +1,4 @@ +#include "MantidAPI/AlgorithmManager.h" #include "MantidQtMantidWidgets/MantidHelpWindow.h" #include "MantidQtMantidWidgets/pqHelpWindow.h" #include "MantidQtAPI/InterfaceManager.h" @@ -183,23 +184,38 @@ void MantidHelpWindow::showWikiPage(const QString &page) { */ void MantidHelpWindow::showAlgorithm(const string &name, const int version) { auto versionStr("-v" + boost::lexical_cast<string>(version)); - if (version <= 0) + if (version <= 0) { versionStr = ""; // let the redirect do its thing + } + QString help_url(""); + if (!name.empty()) { + auto alg = Mantid::API::AlgorithmManager::Instance().createUnmanaged(name); + help_url = QString::fromStdString(alg->helpURL()); + } if (bool(g_helpWindow)) { - QString url(BASE_URL); - url += "algorithms/"; - if (name.empty()) - url += "index.html"; - else - url += QString(name.c_str()) + QString(versionStr.c_str()) + ".html"; - this->showHelp(url); - } else // qt-assistant disabled - { - if (name.empty()) - this->showWikiPage(std::string("Category:Algorithms")); - else - this->showWikiPage(name); + if (help_url.isEmpty()) { + QString url(BASE_URL); + url += "algorithms/"; + if (name.empty()) { + url += "index.html"; + } else { + url += QString(name.c_str()) + QString(versionStr.c_str()) + ".html"; + } + this->showHelp(url); + } else { + this->showHelp(help_url); + } + } else { // qt-assistant disabled + if (help_url.isEmpty()) { + if (name.empty()) { + this->showWikiPage(std::string("Category:Algorithms")); + } else { + this->showWikiPage(name); + } + } else { + this->openWebpage(help_url); + } } } diff --git a/MantidQt/MantidWidgets/src/pqHelpWindow.cxx b/MantidQt/MantidWidgets/src/pqHelpWindow.cxx index 8e0bd48e30d88dae1e6920d7e3db2dfcf1e5d042..c93d46055507054123f222ed6dfb6d8f924ed4be 100644 --- a/MantidQt/MantidWidgets/src/pqHelpWindow.cxx +++ b/MantidQt/MantidWidgets/src/pqHelpWindow.cxx @@ -53,7 +53,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <QUrl> #include <QWebHistory> #include <QWebView> -#include <iostream> using MantidQt::API::MantidDesktopServices; @@ -305,7 +304,7 @@ void pqHelpWindow::errorMissingPage(const QUrl& url) //----------------------------------------------------------------------------- void pqHelpWindow::showPage(const QString& url) { - this->showPage(QUrl(url)); + this->showPage(QUrl::fromUserInput(url)); } //----------------------------------------------------------------------------- diff --git a/docs/source/release/v3.10.0/framework.rst b/docs/source/release/v3.10.0/framework.rst index e42695c21e6252a4ccdc7c7b01492e2bc02d3cb3..14805eed1e49432087a3c5c9f96e2b4507c6878d 100644 --- a/docs/source/release/v3.10.0/framework.rst +++ b/docs/source/release/v3.10.0/framework.rst @@ -18,6 +18,8 @@ Algorithms ---------- - Removed the optional flag ``LocationParameters`` from ``ClearInstrumentParameters``. +- New method `IAlgorithm::helpURL` returns an optional documentation webpage. Useful when registering Python + algorithms at runtime that are not part of the Mantid distribution. New ###