Commit 8ea0ebcd authored by Samuel Jones's avatar Samuel Jones
Browse files

Re #25383 Exposure of InterfaceManager and adding all Qt5 libraries.

- InterfaceManager exposure increased via Sip
- UserSubWindow minimal exposure to python via Sip
- Build seperate targets for Reflectometry GUI for Qt4 and Qt5
- Plotter class for Reflectometry GUI has support for Qt5/Workbench
- Removed empty .py file from muon_analysis.
parent 3ee7b168
......@@ -30,7 +30,7 @@ mantidqt.python_interfaces_directory = @MANTID_ROOT@/scripts
framework.plugins.directory = @FRAMEWORK_PLUGINS_DIR@
# Libraries to skip. The strings are searched for when loading libraries so they don't need to be exact
framework.plugins.exclude = Qt4;Qt5
framework.plugins.exclude = Qt4
# Where to find mantid paraview plugin libraries
pvplugins.directory = @PV_PLUGINS_DIR@
......
......@@ -88,7 +88,7 @@ Directory Properties
| ``framework.plugins.directory`` | The path to the directory that contains the | ``../plugins`` |
| | Mantid plugin libraries | |
+--------------------------------------+---------------------------------------------------+-------------------------------------+
| ``framework.plugins.exclude`` | A list of substrings to allow libraries to be | ``Qt4;Qt5`` |
| ``framework.plugins.exclude`` | A list of substrings to allow libraries to be | ``Qt4`` |
| | skipped | |
+--------------------------------------+---------------------------------------------------+-------------------------------------+
| ``instrumentDefinition.directory`` | Where to load instrument definition files from | ``../Test/Instrument`` |
......
......@@ -51,6 +51,7 @@ from mantidqt.widgets.codeeditor.execution import PythonCodeExecution # noqa
from mantidqt.utils.qt import (add_actions, create_action, plugins,
widget_updates_disabled) # noqa
from mantidqt.project.project import Project # noqa
from mantidqt.interfacemanager import InterfaceManager # noqa
# Pre-application setup
plugins.setup_library_paths()
......@@ -309,11 +310,28 @@ class MainWindow(QMainWindow):
add_actions(self.file_menu, self.file_menu_actions)
add_actions(self.view_menu, self.view_menu_actions)
def launch_custom_gui(self, filename):
def launch_custom_python_gui(self, filename):
executioner = PythonCodeExecution()
executioner.sig_exec_error.connect(lambda errobj: logger.warning(str(errobj)))
executioner.execute(open(filename).read(), filename)
def launch_custom_cpp_gui(self, subwindow):
subwindow.show()
def populate_cpp_interfaces_list(self, blacklist):
interface_manager = InterfaceManager()
interface_names = interface_manager.getUserSubWindowKeys()
interfaces = {}
for interface_name in interface_names:
if interface_name not in blacklist:
interfaces[interface_name] = interface_manager.createSubWindow(interface_name, self)
else:
logger.information('Not adding gui "{}"'.format(interface_name))
return interfaces
def populate_interfaces_menu(self):
interface_dir = ConfigService['mantidqt.python_interfaces_directory']
items = ConfigService['mantidqt.python_interfaces'].split()
......@@ -338,6 +356,8 @@ class MainWindow(QMainWindow):
temp.append(scriptname)
interfaces[key] = temp
interfaces.update(self.populate_cpp_interfaces_list(GUI_BLACKLIST))
# add the interfaces to the menu
keys = list(interfaces.keys())
keys.sort()
......@@ -346,9 +366,17 @@ class MainWindow(QMainWindow):
names = interfaces[key]
names.sort()
for name in names:
action = submenu.addAction(name.replace('.py', '').replace('_', ' '))
script = os.path.join(interface_dir, name)
action.triggered.connect(lambda checked, script=script: self.launch_custom_gui(script))
if '.py' in name:
name.replace('.py', '')
name.replace('_', ' ')
action = submenu.addAction(name)
script = os.path.join(interface_dir, name)
action.triggered.connect(lambda checked_py, script=script: self.launch_custom_python_gui(script))
else:
interface = interfaces[key]
action = submenu.addAction(name)
action.triggered.connect(lambda checked_cpp, interface=interface:
self.launch_custom_cpp_gui(interface))
def add_dockwidget(self, plugin):
"""Create a dockwidget around a plugin and add the dock to window"""
......
......@@ -78,6 +78,7 @@ if ( ENABLE_WORKBENCH )
LINK_LIBS
${common_link_libs}
MantidQtWidgetsCommonQt5
MantidQtWidgetsMplCppQt5
Qt5::Core
Qt5::Gui
Qt5::Widgets
......
......@@ -224,6 +224,16 @@ public:
GenericDialog(QWidget *parent = nullptr);
};
class UserSubWindow : QMainWindow {
%TypeHeaderCode
#include "MantidQtWidgets/Common/UserSubWindow.h"
using namespace MantidQt::API;
%End
public:
UserSubWindow(QWidget *parent = nullptr);
protected:
virtual void initLayout() = 0;
};
class InterfaceManager {
%TypeHeaderCode
......@@ -239,6 +249,10 @@ public:
const QString &optionalMsg = QString(),
const QStringList &enabled = QStringList(),
const QStringList &disabled = QStringList());
UserSubWindow *createSubWindow(
const QString &interface_name,
QWidget *parent = nullptr);
QStringList getUserSubWindowKeys() const;
};
// ---------------------------------
......
......@@ -37,6 +37,7 @@ set ( UI_FILES
mtd_add_qt_library (TARGET_NAME MantidScientificInterfacesISISReflectometry
QT_VERSION 4
SRC ${SRC_FILES}
MOC ${MOC_FILES}
NOMOC ${INC_FILES}
......@@ -62,3 +63,30 @@ mtd_add_qt_library (TARGET_NAME MantidScientificInterfacesISISReflectometry
LINUX_INSTALL_RPATH
"\$ORIGIN/../../${LIB_DIR}"
)
mtd_add_qt_library (TARGET_NAME MantidScientificInterfacesISISReflectometry
QT_VERSION 5
SRC ${SRC_FILES}
MOC ${MOC_FILES}
NOMOC ${INC_FILES}
UI ${UI_FILES}
DEFS IN_MANTIDQT_ISISREFLECTOMETRY
PRECOMPILED PrecompiledHeader.h
INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}
LINK_LIBS
${TCMALLOC_LIBRARIES_LINKTIME}
${CORE_MANTIDLIBS}
${POCO_LIBRARIES}
${Boost_LIBRARIES}
${JSONCPP_LIBRARIES}
MTD_QT_LINK_LIBS
MantidQtWidgetsCommon
MantidQtWidgetsMplCpp
INSTALL_DIR_BASE
${PLUGINS_DIR}
OSX_INSTALL_RPATH
@loader_path/../../Contents/MacOS
LINUX_INSTALL_RPATH
"\$ORIGIN/../../${LIB_DIR}"
)
......@@ -9,6 +9,15 @@
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
#include "RunsTableView.h"
#else
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidQtWidgets/MplCpp/Plot.h"
#include <QHash>
#include <QString>
#include <QVariant>
using namespace MantidQt::Widgets::MplCpp;
#endif
namespace MantidQt {
......@@ -21,6 +30,7 @@ Plotter::Plotter(RunsTableView *runsTableView)
void Plotter::reflectometryPlot(const std::vector<std::string> &workspaces) {
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
// MantidPlot plotting
if (!workspaces.empty()) {
std::string pythonSrc;
pythonSrc += "base_graph = None\n";
......@@ -33,8 +43,20 @@ void Plotter::reflectometryPlot(const std::vector<std::string> &workspaces) {
this->runPython(pythonSrc);
}
#else
throw std::runtime_error(
"Plotter::reflectometryPlot() not implemented for Qt >= 5");
// Workbench Plotting
std::vector<MatrixWorkspace_sptr> workspaceObjects;
for (const auto &workspaceName : workspaces) {
workspaceObjects.emplace_back(boost::dynamic_pointer_cast<MatrixWorkspace>(
AnalysisDataService::Instance().retrieve(workspaceName)));
}
QHash<QString, QVariant> ax_properties;
ax_properties[QString("yscale")] = QVariant("log");
ax_properties[QString("xscale")] = QVariant("log");
// plot(workspaces, spectrum_nums, wksp_indices, fig, plot_kwargs,
// ax_properties, windows_title, errors, overplot)
plot(workspaceObjects, boost::none, boost::none, boost::none, boost::none,
ax_properties, boost::none, false, true);
#endif
}
......
......@@ -9,9 +9,8 @@
#include "Common/DllConfig.h"
#include <QMap>
#include <QSet>
#include <QString>
#include <QtGlobal>
#include <string>
#include <vector>
namespace MantidQt {
......
......@@ -42,12 +42,14 @@ set ( QT5_SRC_FILES
src/MultifitSetupDialog.cpp
src/MWRunFiles.cpp
src/OptionsPropertyWidget.cpp
src/ParseKeyValueString.cpp
src/pixmaps.cpp
src/PluginLibraries.cpp
src/ProcessingAlgoWidget.cpp
src/PropertyHandler.cpp
src/PropertyWidget.cpp
src/PropertyWidgetFactory.cpp
src/ProgressableView.cpp
src/PythonRunner.cpp
src/QtSignalChannel.cpp
src/RenameParDialog.cpp
......@@ -55,6 +57,7 @@ set ( QT5_SRC_FILES
src/SequentialFitDialog.cpp
src/SelectFunctionDialog.cpp
src/SelectWorkspacesDialog.cpp
src/SlitCalculator.cpp
src/TextPropertyWidget.cpp
src/TSVSerialiser.cpp
src/UserFunctionDialog.cpp
......@@ -128,10 +131,8 @@ set ( QT5_MOC_FILES
inc/MantidQtWidgets/Common/FitPropertyBrowser.h
inc/MantidQtWidgets/Common/FunctionBrowser.h
inc/MantidQtWidgets/Common/GenericDialog.h
inc/MantidQtWidgets/Common/Hint.h
inc/MantidQtWidgets/Common/HintingLineEdit.h
inc/MantidQtWidgets/Common/InputController.h
inc/MantidQtWidgets/Common/InterfaceManager.h
inc/MantidQtWidgets/Common/LineEditWithClear.h
inc/MantidQtWidgets/Common/ListPropertyWidget.h
inc/MantidQtWidgets/Common/ManageUserDirectories.h
......@@ -154,11 +155,11 @@ set ( QT5_MOC_FILES
inc/MantidQtWidgets/Common/SequentialFitDialog.h
inc/MantidQtWidgets/Common/SelectFunctionDialog.h
inc/MantidQtWidgets/Common/SelectWorkspacesDialog.h
inc/MantidQtWidgets/Common/SlitCalculator.h
inc/MantidQtWidgets/Common/TextPropertyWidget.h
inc/MantidQtWidgets/Common/UserFunctionDialog.h
inc/MantidQtWidgets/Common/UserSubWindow.h
inc/MantidQtWidgets/Common/VatesViewerInterface.h
inc/MantidQtWidgets/Common/WorkspaceIcons.h
inc/MantidQtWidgets/Common/WorkspaceObserver.h
inc/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidget.h
inc/MantidQtWidgets/Common/WorkspacePresenter/WorkspaceTreeWidgetSimple.h
......@@ -203,15 +204,20 @@ set ( QT5_INC_FILES
inc/MantidQtWidgets/Common/FileDialogHandler.h
inc/MantidQtWidgets/Common/FlowLayout.h
inc/MantidQtWidgets/Common/HelpWindow.h
inc/MantidQtWidgets/Common/Hint.h
inc/MantidQtWidgets/Common/IFunctionBrowser.h
inc/MantidQtWidgets/Common/InterfaceFactory.h
inc/MantidQtWidgets/Common/InterfaceManager.h
inc/MantidQtWidgets/Common/MantidDesktopServices.h
inc/MantidQtWidgets/Common/MantidTreeWidgetItem.h
inc/MantidQtWidgets/Common/MultifitSetupDialog.h
inc/MantidQtWidgets/Common/ParseKeyValueString.h
inc/MantidQtWidgets/Common/pixmaps.h
inc/MantidQtWidgets/Common/PropertyWidgetFactory.h
inc/MantidQtWidgets/Common/ProgressableView.h
inc/MantidQtWidgets/Common/SequentialFitDialog.h
inc/MantidQtWidgets/Common/WidgetScrollbarDecorator.h
inc/MantidQtWidgets/Common/WorkspaceIcons.h
inc/MantidQtWidgets/Common/Batch/QtStandardItemTreeAdapter.h
inc/MantidQtWidgets/Common/Batch/QtBasicNavigation.h
inc/MantidQtWidgets/Common/Batch/QtTreeCursorNavigation.h
......@@ -449,7 +455,6 @@ set ( MOC_FILES
inc/MantidQtWidgets/Common/AlgorithmSelectorWidget.h
inc/MantidQtWidgets/Common/CheckboxHeader.h
inc/MantidQtWidgets/Common/Batch/JobTreeView.h
inc/MantidQtWidgets/Common/Batch/MockJobTreeView.h
inc/MantidQtWidgets/Common/Batch/JobTreeViewSignalAdapter.h
inc/MantidQtWidgets/Common/DataProcessorUI/AbstractTreeModel.h
inc/MantidQtWidgets/Common/DataProcessorUI/QtCommandAdapter.h
......@@ -673,6 +678,7 @@ set ( INC_FILES
inc/MantidQtWidgets/Common/Batch/ExtractSubtrees.h
inc/MantidQtWidgets/Common/Batch/FindSubtreeRoots.h
inc/MantidQtWidgets/Common/Batch/BuildSubtreeItems.h
inc/MantidQtWidgets/Common/Batch/MockJobTreeView.h
)
set ( UI_FILES
......
......@@ -29,8 +29,9 @@ MANTID_MPLCPP_DLL Python::Object
plot(std::vector<MatrixWorkspace_sptr> workspaces,
boost::optional<std::vector<std::size_t>> spectrum_nums,
boost::optional<std::vector<std::size_t>> wksp_indices,
boost::optional<Python::Object>, boost::optional<QHash<QString, QVariant>>,
boost::optional<QHash<QString, QVariant>>,
boost::optional<Python::Object> fig,
boost::optional<QHash<QString, QVariant>> plot_kwargs,
boost::optional<QHash<QString, QVariant>> ax_properties,
boost::optional<std::string> window_title, bool errors = false,
bool overplot = false);
......
......@@ -20,7 +20,27 @@ namespace detail {
const sipAPIDef *sipAPI();
} // namespace detail
template <typename T> T *extract(const Object &obj);
/**
* Extract a C++ object of type T from the Python object
* @param obj A sip-wrapped Python object
*/
template <typename T> T *extract(const Object &obj) {
const auto sipapi = detail::sipAPI();
if (!PyObject_TypeCheck(obj.ptr(), sipapi->api_wrapper_type)) {
throw std::runtime_error("extract() - Object is not a sip-wrapped type.");
}
// transfer ownership from python to C++
sipapi->api_transfer_to(obj.ptr(), 0);
// reinterpret to sipWrapper
auto wrapper = reinterpret_cast<sipSimpleWrapper *>(obj.ptr());
#if (SIP_API_MAJOR_NR == 8 && SIP_API_MINOR_NR >= 1) || SIP_API_MAJOR_NR > 8
return static_cast<T *>(sipapi->api_get_address(wrapper));
#elif SIP_API_MAJOR_NR == 8
return static_cast<T *>(wrapper->data);
#else
return static_cast<T *>(wrapper->u.cppPtr);
#endif
}
} // namespace Python
} // namespace MplCpp
......
......@@ -8,6 +8,7 @@
#include "MantidQtWidgets/MplCpp/Plot.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidPythonInterface/core/GlobalInterpreterLock.h"
#include "MantidQtWidgets/MplCpp/Python/Object.h"
#include "MantidQtWidgets/MplCpp/Python/QHashToDict.h"
using namespace Mantid::API;
......@@ -33,8 +34,8 @@ Python::Object plot(std::vector<MatrixWorkspace_sptr> workspaces,
UNUSED_ARG(window_title)
UNUSED_ARG(errors)
UNUSED_ARG(overplot)
auto funcs = PyImport_ImportModule("mantidqt.plotting.functions");
UNUSED_ARG(funcs)
// auto funcs = PyImport_ImportModule("mantidqt.plotting.functions");
// UNUSED_ARG(funcs)
GlobalInterpreterLock lock;
// workspaces, spectrum_nums, wksp_indices, errors, overplot, fig,
// plot_kwargs, ax_properties, window_title;
......
......@@ -6,6 +6,7 @@
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidQtWidgets/MplCpp/Python/Sip.h"
#include <sip.h>
namespace MantidQt {
namespace Widgets {
......@@ -16,7 +17,7 @@ namespace detail {
/**
* @return A pointer to the C++ sip api object
*/
const sipAPIDef *Sip::sipAPI() {
const sipAPIDef *sipAPI() {
static const sipAPIDef *sip_API = nullptr;
if (sip_API)
return sip_API;
......@@ -48,28 +49,6 @@ const sipAPIDef *Sip::sipAPI() {
}
} // namespace detail
/**
* Extract a C++ object of type T from the Python object
* @param obj A sip-wrapped Python object
*/
template <typename T> T *Sip::extract(const Object &obj) {
const auto sipapi = detail::sipAPI();
if (!PyObject_TypeCheck(obj.ptr(), sipapi->api_wrapper_type)) {
throw std::runtime_error("extract() - Object is not a sip-wrapped type.");
}
// transfer ownership from python to C++
sipapi->api_transfer_to(obj.ptr(), 0);
// reinterpret to sipWrapper
auto wrapper = reinterpret_cast<sipSimpleWrapper *>(obj.ptr());
#if (SIP_API_MAJOR_NR == 8 && SIP_API_MINOR_NR >= 1) || SIP_API_MAJOR_NR > 8
return static_cast<T *>(sipapi->api_get_address(wrapper));
#elif SIP_API_MAJOR_NR == 8
return static_cast<T *>(wrapper->data);
#else
return static_cast<T *>(wrapper->u.cppPtr);
#endif
}
} // namespace Python
} // namespace MplCpp
} // namespace Widgets
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment