Commit f5cff075 authored by Samuel Jones's avatar Samuel Jones
Browse files

Re #24350 Add Encoder Full

parent 8263eddf
......@@ -59,6 +59,7 @@ plugins.setup_library_paths()
from workbench.config import APPNAME, CONF, ORG_DOMAIN, ORGANIZATION # noqa
from workbench.plotting.globalfiguremanager import GlobalFigureManager # noqa
from workbench.windows.windowfinder import find_all_windows_that_have_an_encoder # noqa
# -----------------------------------------------------------------------------
......@@ -213,7 +214,7 @@ class MainWindow(QMainWindow):
self.widgets.append(self.workspacewidget)
# Set up the project object
self.project = Project(GlobalFigureManager)
self.project = Project(GlobalFigureManager, find_all_windows_that_have_an_encoder)
# uses default configuration as necessary
self.readSettings(CONF)
......
# Mantid Repository : https://github.com/mantidproject/mantid
#
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
# NScD Oak Ridge National Laboratory, European Spallation Source
# & Institut Laue - Langevin
# SPDX - License - Identifier: GPL - 3.0 +
# Mantid Repository : https://github.com/mantidproject/mantid
#
# Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
# NScD Oak Ridge National Laboratory, European Spallation Source
# & Institut Laue - Langevin
# SPDX - License - Identifier: GPL - 3.0 +
from __future__ import (absolute_import, division, print_function, unicode_literals)
from qtpy.QtWidgets import QApplication
from workbench.plotting.globalfiguremanager import GlobalFigureManager
from mantidqt.project.encoderfactory import EncoderFactory
def find_plot_windows():
"""
Finds the currently open plot windows and returns them in a dict
:return: ObservableDict; of currently open plots
"""
return GlobalFigureManager.figs
def find_all_windows_that_have_an_encoder():
"""
Finds all windows and then checks if they have an encoder, if they do return them in a list of windows and encoders.
:return: List of Lists of Windows and Encoders; Window at index 0 and Encoder at index 1 in each sub-list.
"""
# Get all top level widgets and check if they have an encoder
list_of_windows_and_encoder = []
windows = QApplication.topLevelWidgets()
for window in windows:
return_value = EncoderFactory.find_encoder(window)
if return_value is not None:
list_of_windows_and_encoder.append([window, return_value])
return list_of_windows_and_encoder
......@@ -13,9 +13,14 @@ class EncoderFactory(object):
encoder_list = []
@classmethod
def find_encoder(cls, tag):
def find_encoder(cls, obj):
"""
This assumes that obj is of a class that has an encode else it returns None
:param obj: The object for encoding
:return: Encoder or None; Returns the Encoder of the
"""
for encoder in cls.encoder_list:
if encoder().has_tag(tag):
if encoder().has_tag(obj.__class__.__name__):
return encoder
return None
......
......@@ -18,7 +18,12 @@ from mantidqt.project.projectsaver import ProjectSaver
class Project(AnalysisDataServiceObserver):
def __init__(self, globalfiguremanager_instance):
def __init__(self, globalfiguremanager_instance, interface_populating_function):
"""
:param globalfiguremanager_instance: The global figure manager instance used in this project.
:param interface_populating_function: The interface populating function which returns a list of lists of windows
and encoders
"""
super(Project, self).__init__()
# Has the project been saved, to Access this call .saved
self.__saved = True
......@@ -33,6 +38,8 @@ class Project(AnalysisDataServiceObserver):
self.plot_gfm = globalfiguremanager_instance
self.plot_gfm.add_observer(self)
self.interface_populating_function = interface_populating_function
def __get_saved(self):
return self.__saved
......@@ -68,9 +75,10 @@ class Project(AnalysisDataServiceObserver):
def _save(self):
workspaces_to_save = AnalysisDataService.getObjectNames()
plots_to_save = self.plot_gfm.figs
interfaces_to_save = self.interface_populating_function()
project_saver = ProjectSaver(self.project_file_ext)
project_saver.save_project(directory=self.last_project_location, workspace_to_save=workspaces_to_save,
plots_to_save=plots_to_save)
plots_to_save=plots_to_save, interfaces_to_save=interfaces_to_save)
self.__saved = True
def _file_dialog(self, accept_mode, file_mode, file_filter=None):
......
......@@ -20,12 +20,13 @@ class ProjectSaver(object):
def __init__(self, project_file_ext):
self.project_file_ext = project_file_ext
def save_project(self, directory, workspace_to_save=None, plots_to_save=None):
def save_project(self, directory, workspace_to_save=None, plots_to_save=None, interfaces_to_save=None):
"""
The method that will actually save the project and call relevant savers for workspaces, plots, interfaces etc.
:param directory: String; The directory of the
:param workspace_to_save: List; of Strings that will have workspace names in it, if None will save all
:param plots_to_save: List; of matplotlib.figure objects to save to the project file.
:param interfaces_to_save: List of Lists of Window and Encoder; the interfaces to save and the encoders to use
:return: None; If the method cannot be completed.
"""
# Check if the directory doesn't exist
......@@ -34,7 +35,7 @@ class ProjectSaver(object):
return
# Check this isn't saving a blank project file
if workspace_to_save is None and plots_to_save is None:
if workspace_to_save is None and plots_to_save is None and interfaces_to_save is None:
logger.warning("Can not save an empty project")
return
......@@ -45,27 +46,37 @@ class ProjectSaver(object):
# Generate plots
plots_to_save_list = PlotsSaver().save_plots(plots_to_save)
# Save interfaces
interfaces = {}
for interface in interfaces_to_save:
# Add to the dictionary encoded data with the key as the first tag in the list on the encoder attributes
encoder = interface[1]()
interfaces[interface[1].__class__.__name__] = encoder.encode(interface[0], directory)
# Pass dicts to Project Writer
writer = ProjectWriter(workspace_names=workspace_saver.get_output_list(),
plots_to_save=plots_to_save_list,
interfaces_to_save=interfaces,
save_location=directory,
project_file_ext=self.project_file_ext)
writer.write_out()
class ProjectWriter(object):
def __init__(self, save_location, workspace_names, project_file_ext, plots_to_save):
def __init__(self, save_location, workspace_names, project_file_ext, plots_to_save, interfaces_to_save):
self.workspace_names = workspace_names
self.directory = save_location
self.project_file_ext = project_file_ext
self.plots_to_save = plots_to_save
self.interfaces_to_save = interfaces_to_save
def write_out(self):
"""
Write out the project file that contains workspace names, interfaces information, plot preferences etc.
"""
# Get the JSON string versions
to_save_dict = {"workspaces": self.workspace_names, "plots": self.plots_to_save}
to_save_dict = {"workspaces": self.workspace_names, "plots": self.plots_to_save,
"interfaces": self.interfaces_to_save}
# Open file and save the string to it alongside the workspace_names
if not os.path.isdir(self.directory):
......@@ -73,6 +84,6 @@ class ProjectWriter(object):
file_path = os.path.join(self.directory, (os.path.basename(self.directory) + self.project_file_ext))
try:
with open(file_path, "w+") as f:
dump(obj=to_save_dict, fp=f)
dump(obj=to_save_dict, fp=f, indent=2)
except Exception:
logger.warning("JSON project file unable to be opened/written to")
......@@ -25,3 +25,12 @@ public:
bool overlay(const QString & ws_name);
};
class InstrumentWidgetEncoder {
%TypeHeaderCode
#include "MantidQtWidgets/InstrumentView/InstrumentWidgetEncoder.h"
%End
public:
InstrumentWidgetEncoder();
QMap<QString, QVariant> encode(const InstrumentWidget &obj,
const QString &projectPath) /ReleaseGIL/;
};
......@@ -6,14 +6,11 @@
# SPDX - License - Identifier: GPL - 3.0 +
# This file is part of the mantidqt package
#
#
from __future__ import (absolute_import, unicode_literals)
# 3rd party imports
from __future__ import (absolute_import, division, print_function, unicode_literals)
# local imports
from mantidqt.utils.qt import import_qt
# Import widget from C++ wrappers
InstrumentWidget = import_qt('._instrumentview', 'mantidqt.widgets.instrumentview',
'InstrumentWidget')
InstrumentWidgetEncoder = import_qt('._instrumentview', 'mantidqt.widgets.instrumentview',
'InstrumentWidgetEncoder')
......@@ -8,11 +8,15 @@
#
from __future__ import (absolute_import, division, print_function, unicode_literals)
from mantidqt.widgets.instrumentview.interpreterimports import InstrumentWidgetEncoder
from qtpy.QtGui import QColor
class InstrumentViewAttributes(object):
# WARNING: If you delete a tag from here instead of adding a new one, it will make old project files obsolete so
# just add an extra tag to the list e.g. ["InstrumentView", "IView"]
tags = ["InstrumentView"]
# just add an extra tag to the list e.g. ["InstrumentWidget", "IWidget"]
tags = ["InstrumentView", "InstrumentWidget"]
class Decoder(InstrumentViewAttributes):
......@@ -32,11 +36,19 @@ class Decoder(InstrumentViewAttributes):
class Encoder(InstrumentViewAttributes):
def __init__(self):
super(Encoder, self).__init__()
self.widget_encoder = InstrumentWidgetEncoder()
def encode(self, obj):
if obj is None:
def encode(self, obj, project_path=None):
if obj is None or project_path is None:
return None
return {}
instrument_widget = obj.layout().itemAt(0).widget()
encoded_instrumentview = self.widget_encoder.encode(instrument_widget, project_path)
# A color is passed to python as a QColor for certain objects and it needs to be fixed
r, g, b, a = encoded_instrumentview["surface"]["backgroundColor"].getRgb()
encoded_instrumentview["surface"]["backgroundColor"] = {"red": r, "green": g, "blue": b, "alpha": a}
return encoded_instrumentview
@classmethod
def has_tag(cls, tag):
......
......@@ -7,11 +7,11 @@ set ( SRC_FILES
src/GLColor.cpp
src/GLObject.cpp
src/InstrumentActor.cpp
src/InstrumentEncoder.cpp
src/InstrumentDecoder.cpp
src/InstrumentTreeModel.cpp
src/InstrumentTreeWidget.cpp
src/InstrumentWidget.cpp
src/InstrumentWidgetEncoder.cpp
src/InstrumentWidgetDecoder.cpp
src/InstrumentWidgetMaskTab.cpp
src/InstrumentWidgetPickTab.cpp
src/InstrumentWidgetRenderTab.cpp
......@@ -90,11 +90,11 @@ set ( INC_FILES
inc/MantidQtWidgets/InstrumentView/GLObject.h
inc/MantidQtWidgets/InstrumentView/GridTextureFace.h
inc/MantidQtWidgets/InstrumentView/InstrumentActor.h
inc/MantidQtWidgets/InstrumentView/InstrumentEncoder.h
inc/MantidQtWidgets/InstrumentView/InstrumentDecoder.h
inc/MantidQtWidgets/InstrumentView/InstrumentTreeModel.h
inc/MantidQtWidgets/InstrumentView/InstrumentTreeWidget.h
inc/MantidQtWidgets/InstrumentView/InstrumentWidget.h
inc/MantidQtWidgets/InstrumentView/InstrumentWidgetEncoder.h
inc/MantidQtWidgets/InstrumentView/InstrumentWidgetDecoder.h
inc/MantidQtWidgets/InstrumentView/InstrumentRenderer.h
inc/MantidQtWidgets/InstrumentView/InstrumentWidgetMaskTab.h
inc/MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h
......
......@@ -283,6 +283,8 @@ private:
std::unique_ptr<Mantid::Geometry::ComponentInfo> m_physicalComponentInfo;
std::unique_ptr<Mantid::Geometry::DetectorInfo> m_physicalDetectorInfo;
std::unique_ptr<InstrumentRenderer> m_renderer;
friend class InstrumentWidgetEncoder;
};
} // namespace MantidWidgets
......
......@@ -51,6 +51,8 @@ class InstrumentActor;
class InstrumentWidgetTab;
class InstrumentWidgetRenderTab;
class InstrumentWidgetMaskTab;
class InstrumentWidgetPickTab;
class InstrumentWidgetTreeTab;
class CollapsiblePanel;
class XIntegrationControl;
class SimpleWidget;
......
......@@ -7,28 +7,31 @@
#ifndef INSTRUMENTWIDGETENCODER_H_
#define INSTRUMENTWIDGETENCODER_H_
#include "MantidQtWidgets/InstrumentView/ColorBar.h"
#include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
#include "MantidQtWidgets/InstrumentView/InstrumentWidgetMaskTab.h"
#include "MantidQtWidgets/InstrumentView/InstrumentWidgetPickTab.h"
#include "MantidQtWidgets/InstrumentView/InstrumentWidgetRenderTab.h"
#include "MantidQtWidgets/InstrumentView/InstrumentWidgetTab.h"
#include "MantidQtWidgets/InstrumentView/InstrumentWidgetTreeTab.h"
#include "MantidQtWidgets/InstrumentView/ColorBar.h"
#include "MantidQtWidgets/InstrumentView/MaskBinsData.h"
#include "MantidQtWidgets/InstrumentView/ProjectionSurface.h"
#include "MantidQtWidgets/InstrumentView/Shape2D.h"
#include "MantidQtWidgets/InstrumentView/InstrumentActor.h"
namespace MantidQt {
namespace MantidWidgets {
class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentWidgetEncoder {
public:
QMap<QString, QVariant> encode(const InstrumentWidget &obj);
InstrumentWidgetEncoder();
QMap<QString, QVariant> encode(const InstrumentWidget &obj, const QString &projectPath);
private:
/// Encode Actor
QMap<QString, QVariant> encodeActor(const std::unique_ptr<InstrumentActor> &obj);
QMap<QString, QVariant>
encodeActor(const std::unique_ptr<InstrumentActor> &obj);
/// Encode all tabs
QMap<QString, QVariant> encodeTabs(const InstrumentWidget &obj);
......@@ -37,7 +40,8 @@ private:
/// Encode pick tab
QMap<QString, QVariant> encodeRenderTab(const InstrumentWidgetRenderTab *tab);
QMap<QString, QVariant> encodeColorMap(Colorbar *bar);
QMap<QString, QVariant>
encodeColorBar(MantidQt::MantidWidgets::ColorBar *bar);
/// Encode mask tab
QMap<QString, QVariant> encodeMaskTab(const InstrumentWidgetMaskTab *tab);
......@@ -48,10 +52,13 @@ private:
QList<QVariant> encodeMaskBinsData(const MaskBinsData &obj);
QMap<QString, QVariant> encodeBinMask(const BinMask &obj);
QMap<QString, QVariant> encodeSurface(const ProjectionSurface_sptr &obj);
QMap<QString, QVariant> encodeShape(const Shape2D &obj);
QMap<QString, QVariant> encodeShape(const Shape2D *obj);
QList<QVariant> encodeMaskShapes(const Shape2DCollection &obj);
QMap<QString, QVariant> encodeShapeProperties(const Shape2D &obj);
QMap<QString, QVariant> encodeAlignmentInfo(const ProjectionSurface_sptr &obj);
QMap<QString, QVariant> encodeShapeProperties(const Shape2D *obj);
QMap<QString, QVariant>
encodeAlignmentInfo(const ProjectionSurface_sptr &obj);
std::string m_projectPath;
};
} // namespace MantidWidgets
......
......@@ -139,7 +139,7 @@ protected:
private:
/// Save masks applied to the view but not to the workspace
bool saveMaskViewToProject(const std::string &name) const;
bool saveMaskViewToProject(const std::string &name, const std::string &projectPath = "") const;
/// Load masks applied to the view but not to the workspace
void loadMaskViewFromProject(const std::string &name);
/// Run the LoadMask algorithm to get a MaskWorkspace
......@@ -207,6 +207,8 @@ protected:
QMap<QtProperty *, QString> m_doublePropertyMap;
QMap<QString, QtProperty *> m_pointPropertyMap;
QMap<QtProperty *, QString> m_pointComponentsMap;
friend class InstrumentWidgetEncoder;
};
} // namespace MantidWidgets
} // namespace MantidQt
......
......@@ -179,6 +179,8 @@ private:
// Temporary caches for values from settings
int m_tubeXUnitsCache;
int m_plotTypeCache;
friend class InstrumentWidgetEncoder;
};
/**
......
......@@ -142,6 +142,7 @@ private: // members
bool m_usingLayerStore;
friend class InstrumentWidget;
friend class InstrumentWidgetEncoder;
};
} // namespace MantidWidgets
} // namespace MantidQt
......
......@@ -21,6 +21,7 @@ class InstrumentTreeWidget;
class EXPORT_OPT_MANTIDQT_INSTRUMENTVIEW InstrumentWidgetTreeTab
: public InstrumentWidgetTab {
Q_OBJECT
friend class InstrumentWidgetEncoder;
public:
explicit InstrumentWidgetTreeTab(InstrumentWidget *instrWidget);
void initSurface() override;
......
......@@ -17,6 +17,15 @@
namespace MantidQt {
namespace MantidWidgets {
/// Range of x values to mask in a spectrum. (Using MaskBins)
struct BinMask {
BinMask(double s = 0.0, double e = 0.0) : start(s), end(e) {}
double start;
double end;
std::vector<size_t> spectra;
};
/**
Class for storing information on masked bins in a workspace.
*/
......@@ -34,14 +43,8 @@ public:
std::string saveToProject() const;
private:
/// Range of x values to mask in a spectrum. (Using MaskBins)
struct BinMask {
BinMask(double s = 0.0, double e = 0.0) : start(s), end(e) {}
double start;
double end;
std::vector<size_t> spectra;
};
QList<BinMask> m_masks;
friend class InstrumentWidgetEncoder;
};
} // namespace MantidWidgets
......
......@@ -385,6 +385,8 @@ private:
/// Set when the picking image must be redrawn regardless of the interaction
/// mode
mutable bool m_redrawPicking;
friend class InstrumentWidgetEncoder;
};
using ProjectionSurface_sptr = boost::shared_ptr<ProjectionSurface>;
......
......@@ -187,6 +187,8 @@ private:
/// Instantiate specifc shapes from a type string
static Shape2D *loadShape2DFromType(const std::string &type,
const std::string &lines);
friend class InstrumentWidgetEncoder;
};
/**
......
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