Mercurial > octave
changeset 27317:718116e9c7d3
rename Backend to qt_graphics_toolkit
* qt-graphics-toolkit.h, qt-graphics-toolkit.cc: Rename from Backend.h
and Backend.cc. Change all uses.
(class qt_graphics_toolkit): Rename from Backend. Change all uses.
* libgui/graphics/module.mk: Update.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 02 Aug 2019 12:18:48 -0500 |
parents | 22265a75be74 |
children | ae53e56e16f2 |
files | libgui/graphics/Backend.cc libgui/graphics/Backend.h libgui/graphics/ButtonGroup.cc libgui/graphics/Canvas.cc libgui/graphics/ContextMenu.cc libgui/graphics/Object.cc libgui/graphics/Object.h libgui/graphics/ObjectFactory.cc libgui/graphics/ObjectFactory.h libgui/graphics/QtHandlesUtils.cc libgui/graphics/__init_qt__.cc libgui/graphics/module.mk libgui/graphics/qt-graphics-toolkit.cc libgui/graphics/qt-graphics-toolkit.h |
diffstat | 14 files changed, 474 insertions(+), 473 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/graphics/Backend.cc Tue Jul 30 15:00:54 2019 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,338 +0,0 @@ -/* - -Copyright (C) 2011-2019 Michael Goffioul - -This file is part of Octave. - -Octave is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Octave is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -<https://www.gnu.org/licenses/>. - -*/ - -#if defined (HAVE_CONFIG_H) -# include "config.h" -#endif - -#include <cstdint> - -#include <QApplication> -#include <QFontMetrics> -#include <QThread> - -#include "Backend.h" -#include "Logger.h" -#include "Object.h" -#include "ObjectFactory.h" -#include "ObjectProxy.h" -#include "QtHandlesUtils.h" - -#include "event-manager.h" -#include "interpreter.h" - -//#if INTPTR_MAX == INT32_MAX -//# define OCTAVE_PTR_TYPE octave_uint32 -//# define OCTAVE_INTPTR_TYPE uint32_t -//# define OCTAVE_PTR_SCALAR uint32_scalar_value -//#else -# define OCTAVE_PTR_TYPE octave_uint64 -# define OCTAVE_INTPTR_TYPE uint64_t -# define OCTAVE_PTR_SCALAR uint64_scalar_value -//#endif - -namespace QtHandles -{ - - static std::string - toolkitObjectProperty (const graphics_object& go) - { - if (go.isa ("figure")) - return "__plot_stream__"; - else if (go.isa ("uicontrol") - || go.isa ("uipanel") - || go.isa ("uibuttongroup") - || go.isa ("uimenu") - || go.isa ("uicontextmenu") - || go.isa ("uitable") - || go.isa ("uitoolbar") - || go.isa ("uipushtool") - || go.isa ("uitoggletool")) - return "__object__"; - else - qCritical ("QtHandles::Backend: no __object__ property known for object " - "of type %s", go.type ().c_str ()); - - return ""; - } - - Backend::Backend (octave::interpreter& interp) - : QObject (), base_graphics_toolkit ("qt"), m_interpreter (interp), - m_factory (new ObjectFactory ()) - { - if (QThread::currentThread () != QApplication::instance ()->thread ()) - m_factory->moveToThread (QApplication::instance ()->thread ()); - - connect (this, SIGNAL (createObject (Backend *, double)), - m_factory, SLOT (createObject (Backend *, double)), - Qt::BlockingQueuedConnection); - } - - Backend::~Backend (void) - { - delete m_factory; - } - - bool - Backend::initialize (const graphics_object& go) - { - if (go.isa ("figure") - || go.isa ("uicontrol") - || go.isa ("uipanel") - || go.isa ("uibuttongroup") - || go.isa ("uimenu") - || go.isa ("uicontextmenu") - || go.isa ("uitable") - || go.isa ("uitoolbar") - || go.isa ("uipushtool") - || go.isa ("uitoggletool")) - { - // FIXME: We need to unlock the mutex here but we have no way to know if - // if it was previously locked by this thread, and thus if we should - // re-lock it. - gh_manager::unlock (); - - Logger::debug ("Backend::initialize %s from thread %08x", - go.type ().c_str (), QThread::currentThreadId ()); - - ObjectProxy *proxy = new ObjectProxy (); - graphics_object gObj (go); - - OCTAVE_PTR_TYPE tmp (reinterpret_cast<OCTAVE_INTPTR_TYPE> (proxy)); - gObj.get_properties ().set (toolkitObjectProperty (go), tmp); - - emit createObject (this, go.get_handle ().value ()); - - return true; - } - - return false; - } - - void - Backend::update (const graphics_object& go, int pId) - { - // Rule out obvious properties we want to ignore. - if (pId == figure::properties::ID___PLOT_STREAM__ - || pId == uicontrol::properties::ID___OBJECT__ - || pId == uipanel::properties::ID___OBJECT__ - || pId == uibuttongroup::properties::ID___OBJECT__ - || pId == uimenu::properties::ID___OBJECT__ - || pId == uicontextmenu::properties::ID___OBJECT__ - || pId == uitable::properties::ID___OBJECT__ - || pId == uitoolbar::properties::ID___OBJECT__ - || pId == uipushtool::properties::ID___OBJECT__ - || pId == uitoggletool::properties::ID___OBJECT__ - || pId == base_properties::ID___MODIFIED__) - return; - - Logger::debug ("Backend::update %s(%d) from thread %08x", - go.type ().c_str (), pId, QThread::currentThreadId ()); - - ObjectProxy *proxy = toolkitObjectProxy (go); - - if (proxy) - { - if (go.isa ("uicontrol") - && pId == uicontrol::properties::ID_STYLE) - { - // Special case: we need to recreate the control widget - // associated with the octave graphics_object - - finalize (go); - initialize (go); - } - else - proxy->update (pId); - } - } - - void - Backend::finalize (const graphics_object& go) - { - // FIXME: We need to unlock the mutex here but we have no way to know if - // if it was previously locked by this thread, and thus if we should - // re-lock it. - gh_manager::unlock (); - - Logger::debug ("Backend::finalize %s from thread %08x", - go.type ().c_str (), QThread::currentThreadId ()); - - ObjectProxy *proxy = toolkitObjectProxy (go); - - if (proxy) - { - proxy->finalize (); - delete proxy; - - graphics_object gObj (go); - - gObj.get_properties ().set (toolkitObjectProperty (go), Matrix ()); - } - } - - void - Backend::redraw_figure (const graphics_object& go) const - { - if (go.get_properties ().is_visible ()) - { - ObjectProxy *proxy = toolkitObjectProxy (go); - - if (proxy) - proxy->redraw (); - } - } - - void - Backend::show_figure (const graphics_object& go) const - { - if (go.get_properties ().is_visible ()) - { - ObjectProxy *proxy = toolkitObjectProxy (go); - - if (proxy) - proxy->show (); - } - } - - void - Backend::print_figure (const graphics_object& go, - const std::string& term, - const std::string& file_cmd, - const std::string& /*debug_file*/) const - { - ObjectProxy *proxy = toolkitObjectProxy (go); - - if (proxy) - proxy->print (QString::fromStdString (file_cmd), - QString::fromStdString (term)); - } - - uint8NDArray - Backend::get_pixels (const graphics_object& go) const - { - uint8NDArray retval; - - if (go.isa ("figure")) - { - ObjectProxy *proxy = toolkitObjectProxy (go); - - if (proxy) - retval = proxy->get_pixels (); - } - - return retval; - } - - Matrix - Backend::get_text_extent (const graphics_object& go) const - { - Matrix ext (1, 4, 0.0); - - if (go.isa ("uicontrol")) - { - octave_value str = go.get ("string"); - if (! str.isempty ()) - { - const uicontrol::properties& up = - dynamic_cast<const uicontrol::properties&> (go.get_properties ()); - Matrix bb = up.get_boundingbox (false); - QFont font = Utils::computeFont<uicontrol> (up, bb(3)); - QFontMetrics fm (font); - - QString s; - QSize sz; - - if (str.is_string ()) - { - s = QString::fromStdString (str.string_value ()); - sz = fm.size (Qt::TextSingleLine, s); - ext(2) = sz.width (); - ext(3) = sz.height (); - } - else if (str.iscellstr ()) - { - string_vector sv = str.string_vector_value (); - double wd = 0.0; - double hg = 0.0; - for (octave_idx_type ii = 0; ii < sv.numel (); ii++) - { - s = QString::fromStdString (sv(ii)); - sz = fm.size (Qt::TextSingleLine, s); - wd = std::max (wd, static_cast<double> (sz.width ())); - hg = std::max (hg, static_cast<double> (sz.height ())); - } - - ext(2) = wd; - // FIXME: Find a better way to determine the height of e.g. - // listbox uicontrol objects - ext(3) = hg * sv.numel (); - } - } - } - - return ext; - } - - Object* - Backend::toolkitObject (const graphics_object& go) - { - ObjectProxy *proxy = toolkitObjectProxy (go); - - if (proxy) - return proxy->object (); - - return nullptr; - } - - ObjectProxy* - Backend::toolkitObjectProxy (const graphics_object& go) - { - if (go) - { - octave_value ov = go.get (toolkitObjectProperty (go)); - - if (ov.is_defined () && ! ov.isempty ()) - { - OCTAVE_INTPTR_TYPE ptr = ov.OCTAVE_PTR_SCALAR ().value (); - - return reinterpret_cast<ObjectProxy *> (ptr); - } - } - - return nullptr; - } - - void Backend::interpreter_event (const octave::fcn_callback& fcn) - { - octave::event_manager& evmgr = m_interpreter.get_event_manager (); - - evmgr.post_event (fcn); - } - - void Backend::interpreter_event (const octave::meth_callback& meth) - { - octave::event_manager& evmgr = m_interpreter.get_event_manager (); - - evmgr.post_event (meth); - } -};
--- a/libgui/graphics/Backend.h Tue Jul 30 15:00:54 2019 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - -Copyright (C) 2011-2019 Michael Goffioul - -This file is part of Octave. - -Octave is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -Octave is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with Octave; see the file COPYING. If not, see -<https://www.gnu.org/licenses/>. - -*/ - -#if ! defined (octave_Backend_h) -#define octave_Backend_h 1 - -#include <QObject> - -#include "event-manager.h" -#include "graphics.h" - -namespace octave -{ - class interpreter; -} - -namespace QtHandles -{ - class Object; - class ObjectFactory; - class ObjectProxy; - - class Backend : - public QObject, - public base_graphics_toolkit - { - Q_OBJECT - - public: - - Backend (octave::interpreter& interp); - - ~Backend (void); - - bool is_valid (void) const { return true; } - - void redraw_figure (const graphics_object& h) const; - - void show_figure (const graphics_object& h) const; - - void update (const graphics_object& obj, int pId); - - bool initialize (const graphics_object& obj); - - void finalize (const graphics_object& obj); - - void print_figure (const graphics_object& go, - const std::string& term, - const std::string& file_cmd, - const std::string& /*debug_file*/) const; - - uint8NDArray get_pixels (const graphics_object& go) const; - - Matrix get_text_extent (const graphics_object& go) const; - - static Object * toolkitObject (const graphics_object& go); - - static ObjectProxy * toolkitObjectProxy (const graphics_object& go); - - signals: - void createObject (Backend *, double handle); - - public slots: - - void interpreter_event (const octave::fcn_callback& fcn); - void interpreter_event (const octave::meth_callback& meth); - - private: - - octave::interpreter& m_interpreter; - - ObjectFactory *m_factory; - }; - -} - -#endif
--- a/libgui/graphics/ButtonGroup.cc Tue Jul 30 15:00:54 2019 -0500 +++ b/libgui/graphics/ButtonGroup.cc Fri Aug 02 12:18:48 2019 -0500 @@ -39,8 +39,8 @@ #include "ButtonGroup.h" #include "ToggleButtonControl.h" #include "RadioButtonControl.h" -#include "Backend.h" #include "QtHandlesUtils.h" +#include "qt-graphics-toolkit.h" #include "ov-struct.h" @@ -355,7 +355,7 @@ graphics_handle h = pp.get_selectedobject (); gh_manager::auto_lock lock; graphics_object go = gh_manager::get_object (h); - Object *selectedObject = Backend::toolkitObject (go); + Object *selectedObject = qt_graphics_toolkit::toolkitObject (go); ToggleButtonControl *toggle = static_cast<ToggleButtonControl *> (selectedObject); RadioButtonControl *radio = static_cast<RadioButtonControl *>(selectedObject);
--- a/libgui/graphics/Canvas.cc Tue Jul 30 15:00:54 2019 -0500 +++ b/libgui/graphics/Canvas.cc Fri Aug 02 12:18:48 2019 -0500 @@ -33,11 +33,11 @@ #include <QWheelEvent> #include <QRectF> -#include "Backend.h" #include "Canvas.h" #include "ContextMenu.h" #include "GLCanvas.h" #include "QtHandlesUtils.h" +#include "qt-graphics-toolkit.h" #include "annotation-dialog.h" @@ -533,7 +533,7 @@ // FIXME: should we use signal/slot mechanism instead of // directly calling parent fig methods Figure *fig = - dynamic_cast<Figure *> (Backend::toolkitObject (figObj)); + dynamic_cast<Figure *> (qt_graphics_toolkit::toolkitObject (figObj)); axes::properties& ap = Utils::properties<axes> (axesObj); if (fig) @@ -631,7 +631,7 @@ Utils::properties<figure> (figObj) .set_currentaxes (axesObj.get_handle ().as_octave_value ()); - Figure *fig = dynamic_cast<Figure *> (Backend::toolkitObject (figObj)); + Figure *fig = dynamic_cast<Figure *> (qt_graphics_toolkit::toolkitObject (figObj)); MouseMode newMouseMode = NoMode; @@ -928,7 +928,7 @@ { MouseMode newMouseMode = NoMode; - Figure *fig = dynamic_cast<Figure *> (Backend::toolkitObject (figObj)); + Figure *fig = dynamic_cast<Figure *> (qt_graphics_toolkit::toolkitObject (figObj)); if (fig) newMouseMode = fig->mouseMode ();
--- a/libgui/graphics/ContextMenu.cc Tue Jul 30 15:00:54 2019 -0500 +++ b/libgui/graphics/ContextMenu.cc Fri Aug 02 12:18:48 2019 -0500 @@ -26,9 +26,9 @@ #include <QMenu> -#include "Backend.h" #include "ContextMenu.h" #include "QtHandlesUtils.h" +#include "qt-graphics-toolkit.h" namespace QtHandles { @@ -122,7 +122,7 @@ if (go.valid_object ()) { ContextMenu *cMenu = - dynamic_cast<ContextMenu *> (Backend::toolkitObject (go)); + dynamic_cast<ContextMenu *> (qt_graphics_toolkit::toolkitObject (go)); if (cMenu) {
--- a/libgui/graphics/Object.cc Tue Jul 30 15:00:54 2019 -0500 +++ b/libgui/graphics/Object.cc Fri Aug 02 12:18:48 2019 -0500 @@ -27,9 +27,9 @@ #include <QString> #include <QVariant> -#include "Backend.h" #include "Object.h" #include "QtHandlesUtils.h" +#include "qt-graphics-toolkit.h" namespace QtHandles { @@ -179,7 +179,7 @@ { gh_manager::auto_lock lock; - Object *parent = Backend::toolkitObject + Object *parent = qt_graphics_toolkit::toolkitObject (gh_manager::get_object (go.get_parent ())); return parent;
--- a/libgui/graphics/Object.h Tue Jul 30 15:00:54 2019 -0500 +++ b/libgui/graphics/Object.h Fri Aug 02 12:18:48 2019 -0500 @@ -108,11 +108,12 @@ // Store the graphics object directly so that it will exist when // we need it. Previously, it was possible for the graphics - // backend to get a handle to a figure, then have the interpreter - // thread delete the corresponding object before the backend (GUI) - // thread had a chance to display it. It should be OK to store - // this object and use it in both threads (graphics_object uses a - // std::shared_ptr) provided that we protect access with mutex locks. + // toolkit to get a handle to a figure, then have the interpreter + // thread delete the corresponding object before the graphics + // toolkit (GUI) thread had a chance to display it. It should be OK + // to store this object and use it in both threads (graphics_object + // uses a std::shared_ptr) provided that we protect access with + // mutex locks. graphics_object m_go; // Handle to the graphics object. This may be redundant now.
--- a/libgui/graphics/ObjectFactory.cc Tue Jul 30 15:00:54 2019 -0500 +++ b/libgui/graphics/ObjectFactory.cc Fri Aug 02 12:18:48 2019 -0500 @@ -30,7 +30,6 @@ #include "event-manager.h" #include "graphics.h" -#include "Backend.h" #include "ButtonGroup.h" #include "CheckBoxControl.h" #include "ContextMenu.h" @@ -53,11 +52,12 @@ #include "ToggleTool.h" #include "ToolBar.h" #include "QtHandlesUtils.h" +#include "qt-graphics-toolkit.h" namespace QtHandles { void - ObjectFactory::createObject (Backend *backend, double handle) + ObjectFactory::createObject (qt_graphics_toolkit *qt_gtk, double handle) { gh_manager::auto_lock lock; @@ -69,7 +69,7 @@ qWarning ("ObjectFactory::createObject: object is being deleted"); else { - ObjectProxy *proxy = Backend::toolkitObjectProxy (go); + ObjectProxy *proxy = qt_graphics_toolkit::toolkitObjectProxy (go); if (proxy) { @@ -131,12 +131,12 @@ connect (obj, SIGNAL (interpreter_event (const octave::fcn_callback&)), - backend, + qt_gtk, SLOT (interpreter_event (const octave::fcn_callback&))); connect (obj, SIGNAL (interpreter_event (const octave::meth_callback&)), - backend, + qt_gtk, SLOT (interpreter_event (const octave::meth_callback&))); } }
--- a/libgui/graphics/ObjectFactory.h Tue Jul 30 15:00:54 2019 -0500 +++ b/libgui/graphics/ObjectFactory.h Fri Aug 02 12:18:48 2019 -0500 @@ -29,7 +29,7 @@ namespace QtHandles { - class Backend; + class qt_graphics_toolkit; class Object; class ObjectFactory : public QObject @@ -42,7 +42,7 @@ public slots: - void createObject (Backend *, double handle); + void createObject (qt_graphics_toolkit *, double handle); }; };
--- a/libgui/graphics/QtHandlesUtils.cc Tue Jul 30 15:00:54 2019 -0500 +++ b/libgui/graphics/QtHandlesUtils.cc Fri Aug 02 12:18:48 2019 -0500 @@ -33,11 +33,11 @@ #include "ov.h" #include "graphics.h" -#include "Backend.h" #include "Container.h" #include "KeyMap.h" #include "Object.h" #include "QtHandlesUtils.h" +#include "qt-graphics-toolkit.h" #include "oct-string.h" @@ -208,7 +208,7 @@ Matrix figureCurrentPoint (const graphics_object& fig, QMouseEvent *event) { - Object *tkFig = Backend::toolkitObject (fig); + Object *tkFig = qt_graphics_toolkit::toolkitObject (fig); if (tkFig) { @@ -229,7 +229,7 @@ Matrix figureCurrentPoint (const graphics_object& fig) { - Object *tkFig = Backend::toolkitObject (fig); + Object *tkFig = qt_graphics_toolkit::toolkitObject (fig); if (tkFig) {
--- a/libgui/graphics/__init_qt__.cc Tue Jul 30 15:00:54 2019 -0500 +++ b/libgui/graphics/__init_qt__.cc Fri Aug 02 12:18:48 2019 -0500 @@ -37,7 +37,7 @@ #include "interpreter.h" #include "symtab.h" -#include "Backend.h" +#include "qt-graphics-toolkit.h" #include "QtHandlesUtils.h" #include "__init_qt__.h" @@ -65,7 +65,7 @@ octave::gtk_manager& gtk_mgr = interp.get_gtk_manager (); - graphics_toolkit tk (new Backend (interp)); + graphics_toolkit tk (new qt_graphics_toolkit (interp)); gtk_mgr.load_toolkit (tk); octave::interpreter::add_atexit_function ("__shutdown_qt__");
--- a/libgui/graphics/module.mk Tue Jul 30 15:00:54 2019 -0500 +++ b/libgui/graphics/module.mk Fri Aug 02 12:18:48 2019 -0500 @@ -3,8 +3,6 @@ LIBOCTGUI_GRAPHICS_LIB = %reldir%/__init_qt__.la OCTAVE_GUI_GRAPHICS_MOC = \ - %reldir%/moc-annotation-dialog.cc \ - %reldir%/moc-Backend.cc \ %reldir%/moc-ButtonControl.cc \ %reldir%/moc-ButtonGroup.cc \ %reldir%/moc-Canvas.cc \ @@ -21,10 +19,12 @@ %reldir%/moc-PopupMenuControl.cc \ %reldir%/moc-PushTool.cc \ %reldir%/moc-SliderControl.cc \ + %reldir%/moc-Table.cc \ %reldir%/moc-TextEdit.cc \ - %reldir%/moc-Table.cc \ %reldir%/moc-ToggleTool.cc \ - %reldir%/moc-ToolBar.cc + %reldir%/moc-ToolBar.cc \ + %reldir%/moc-annotation-dialog.cc \ + %reldir%/moc-qt-graphics-toolkit.cc $(OCTAVE_GUI_GRAPHICS_MOC): | %reldir%/$(octave_dirstamp) @@ -44,9 +44,6 @@ BUILT_SOURCES += $(__init_qt___UI_H) noinst_HEADERS += \ - %reldir%/__init_qt__.h \ - %reldir%/annotation-dialog.h \ - %reldir%/Backend.h \ %reldir%/BaseControl.h \ %reldir%/ButtonControl.h \ %reldir%/ButtonGroup.h \ @@ -57,8 +54,8 @@ %reldir%/EditControl.h \ %reldir%/Figure.h \ %reldir%/FigureWindow.h \ + %reldir%/GLCanvas.h \ %reldir%/GenericEventNotify.h \ - %reldir%/GLCanvas.h \ %reldir%/KeyMap.h \ %reldir%/ListBoxControl.h \ %reldir%/Logger.h \ @@ -81,14 +78,14 @@ %reldir%/ToggleTool.h \ %reldir%/ToolBar.h \ %reldir%/ToolBarButton.h \ + %reldir%/__init_qt__.h \ + %reldir%/annotation-dialog.h \ %reldir%/gl-select.h \ %reldir%/qopengl-functions.h \ + %reldir%/qt-graphics-toolkit.h \ $(TEMPLATE_SRC) %canon_reldir%___init_qt___la_SOURCES = \ - %reldir%/__init_qt__.cc \ - %reldir%/annotation-dialog.cc \ - %reldir%/Backend.cc \ %reldir%/BaseControl.cc \ %reldir%/ButtonControl.cc \ %reldir%/ButtonGroup.cc \ @@ -120,7 +117,10 @@ %reldir%/ToggleButtonControl.cc \ %reldir%/ToggleTool.cc \ %reldir%/ToolBar.cc \ - %reldir%/gl-select.cc + %reldir%/__init_qt__.cc \ + %reldir%/annotation-dialog.cc \ + %reldir%/gl-select.cc \ + %reldir%/qt-graphics-toolkit.cc TEMPLATE_SRC = \ %reldir%/ToolBarButton.cc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/graphics/qt-graphics-toolkit.cc Fri Aug 02 12:18:48 2019 -0500 @@ -0,0 +1,340 @@ +/* + +Copyright (C) 2011-2019 Michael Goffioul + +This file is part of Octave. + +Octave is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Octave is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +<https://www.gnu.org/licenses/>. + +*/ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include <cstdint> + +#include <QApplication> +#include <QFontMetrics> +#include <QThread> + +#include "Logger.h" +#include "Object.h" +#include "ObjectFactory.h" +#include "ObjectProxy.h" +#include "QtHandlesUtils.h" +#include "qt-graphics-toolkit.h" + +#include "event-manager.h" +#include "interpreter.h" + +//#if INTPTR_MAX == INT32_MAX +//# define OCTAVE_PTR_TYPE octave_uint32 +//# define OCTAVE_INTPTR_TYPE uint32_t +//# define OCTAVE_PTR_SCALAR uint32_scalar_value +//#else +# define OCTAVE_PTR_TYPE octave_uint64 +# define OCTAVE_INTPTR_TYPE uint64_t +# define OCTAVE_PTR_SCALAR uint64_scalar_value +//#endif + +namespace QtHandles +{ + + static std::string + toolkitObjectProperty (const graphics_object& go) + { + if (go.isa ("figure")) + return "__plot_stream__"; + else if (go.isa ("uicontrol") + || go.isa ("uipanel") + || go.isa ("uibuttongroup") + || go.isa ("uimenu") + || go.isa ("uicontextmenu") + || go.isa ("uitable") + || go.isa ("uitoolbar") + || go.isa ("uipushtool") + || go.isa ("uitoggletool")) + return "__object__"; + else + qCritical ("QtHandles::qt_graphics_toolkit: no __object__ property known for object " + "of type %s", go.type ().c_str ()); + + return ""; + } + + qt_graphics_toolkit::qt_graphics_toolkit (octave::interpreter& interp) + : QObject (), base_graphics_toolkit ("qt"), m_interpreter (interp), + m_factory (new ObjectFactory ()) + { + if (QThread::currentThread () != QApplication::instance ()->thread ()) + m_factory->moveToThread (QApplication::instance ()->thread ()); + + connect (this, SIGNAL (createObject (qt_graphics_toolkit *, double)), + m_factory, SLOT (createObject (qt_graphics_toolkit *, double)), + Qt::BlockingQueuedConnection); + } + + qt_graphics_toolkit::~qt_graphics_toolkit (void) + { + delete m_factory; + } + + bool + qt_graphics_toolkit::initialize (const graphics_object& go) + { + if (go.isa ("figure") + || go.isa ("uicontrol") + || go.isa ("uipanel") + || go.isa ("uibuttongroup") + || go.isa ("uimenu") + || go.isa ("uicontextmenu") + || go.isa ("uitable") + || go.isa ("uitoolbar") + || go.isa ("uipushtool") + || go.isa ("uitoggletool")) + { + // FIXME: We need to unlock the mutex here but we have no way to know if + // if it was previously locked by this thread, and thus if we should + // re-lock it. + gh_manager::unlock (); + + Logger::debug ("qt_graphics_toolkit::initialize %s from thread %08x", + go.type ().c_str (), QThread::currentThreadId ()); + + ObjectProxy *proxy = new ObjectProxy (); + graphics_object gObj (go); + + OCTAVE_PTR_TYPE tmp (reinterpret_cast<OCTAVE_INTPTR_TYPE> (proxy)); + gObj.get_properties ().set (toolkitObjectProperty (go), tmp); + + emit createObject (this, go.get_handle ().value ()); + + return true; + } + + return false; + } + + void + qt_graphics_toolkit::update (const graphics_object& go, int pId) + { + // Rule out obvious properties we want to ignore. + if (pId == figure::properties::ID___PLOT_STREAM__ + || pId == uicontrol::properties::ID___OBJECT__ + || pId == uipanel::properties::ID___OBJECT__ + || pId == uibuttongroup::properties::ID___OBJECT__ + || pId == uimenu::properties::ID___OBJECT__ + || pId == uicontextmenu::properties::ID___OBJECT__ + || pId == uitable::properties::ID___OBJECT__ + || pId == uitoolbar::properties::ID___OBJECT__ + || pId == uipushtool::properties::ID___OBJECT__ + || pId == uitoggletool::properties::ID___OBJECT__ + || pId == base_properties::ID___MODIFIED__) + return; + + Logger::debug ("qt_graphics_toolkit::update %s(%d) from thread %08x", + go.type ().c_str (), pId, QThread::currentThreadId ()); + + ObjectProxy *proxy = toolkitObjectProxy (go); + + if (proxy) + { + if (go.isa ("uicontrol") + && pId == uicontrol::properties::ID_STYLE) + { + // Special case: we need to recreate the control widget + // associated with the octave graphics_object + + finalize (go); + initialize (go); + } + else + proxy->update (pId); + } + } + + void + qt_graphics_toolkit::finalize (const graphics_object& go) + { + // FIXME: We need to unlock the mutex here but we have no way to know if + // if it was previously locked by this thread, and thus if we should + // re-lock it. + gh_manager::unlock (); + + Logger::debug ("qt_graphics_toolkit::finalize %s from thread %08x", + go.type ().c_str (), QThread::currentThreadId ()); + + ObjectProxy *proxy = toolkitObjectProxy (go); + + if (proxy) + { + proxy->finalize (); + delete proxy; + + graphics_object gObj (go); + + gObj.get_properties ().set (toolkitObjectProperty (go), Matrix ()); + } + } + + void + qt_graphics_toolkit::redraw_figure (const graphics_object& go) const + { + if (go.get_properties ().is_visible ()) + { + ObjectProxy *proxy = toolkitObjectProxy (go); + + if (proxy) + proxy->redraw (); + } + } + + void + qt_graphics_toolkit::show_figure (const graphics_object& go) const + { + if (go.get_properties ().is_visible ()) + { + ObjectProxy *proxy = toolkitObjectProxy (go); + + if (proxy) + proxy->show (); + } + } + + void + qt_graphics_toolkit::print_figure (const graphics_object& go, + const std::string& term, + const std::string& file_cmd, + const std::string& /*debug_file*/) const + { + ObjectProxy *proxy = toolkitObjectProxy (go); + + if (proxy) + proxy->print (QString::fromStdString (file_cmd), + QString::fromStdString (term)); + } + + uint8NDArray + qt_graphics_toolkit::get_pixels (const graphics_object& go) const + { + uint8NDArray retval; + + if (go.isa ("figure")) + { + ObjectProxy *proxy = toolkitObjectProxy (go); + + if (proxy) + retval = proxy->get_pixels (); + } + + return retval; + } + + Matrix + qt_graphics_toolkit::get_text_extent (const graphics_object& go) const + { + Matrix ext (1, 4, 0.0); + + if (go.isa ("uicontrol")) + { + octave_value str = go.get ("string"); + if (! str.isempty ()) + { + const uicontrol::properties& up = + dynamic_cast<const uicontrol::properties&> (go.get_properties ()); + Matrix bb = up.get_boundingbox (false); + QFont font = Utils::computeFont<uicontrol> (up, bb(3)); + QFontMetrics fm (font); + + QString s; + QSize sz; + + if (str.is_string ()) + { + s = QString::fromStdString (str.string_value ()); + sz = fm.size (Qt::TextSingleLine, s); + ext(2) = sz.width (); + ext(3) = sz.height (); + } + else if (str.iscellstr ()) + { + string_vector sv = str.string_vector_value (); + double wd = 0.0; + double hg = 0.0; + for (octave_idx_type ii = 0; ii < sv.numel (); ii++) + { + s = QString::fromStdString (sv(ii)); + sz = fm.size (Qt::TextSingleLine, s); + wd = std::max (wd, static_cast<double> (sz.width ())); + hg = std::max (hg, static_cast<double> (sz.height ())); + } + + ext(2) = wd; + // FIXME: Find a better way to determine the height of e.g. + // listbox uicontrol objects + ext(3) = hg * sv.numel (); + } + } + } + + return ext; + } + + Object* + qt_graphics_toolkit::toolkitObject (const graphics_object& go) + { + ObjectProxy *proxy = toolkitObjectProxy (go); + + if (proxy) + return proxy->object (); + + return nullptr; + } + + ObjectProxy* + qt_graphics_toolkit::toolkitObjectProxy (const graphics_object& go) + { + if (go) + { + octave_value ov = go.get (toolkitObjectProperty (go)); + + if (ov.is_defined () && ! ov.isempty ()) + { + OCTAVE_INTPTR_TYPE ptr = ov.OCTAVE_PTR_SCALAR ().value (); + + return reinterpret_cast<ObjectProxy *> (ptr); + } + } + + return nullptr; + } + + void + qt_graphics_toolkit::interpreter_event (const octave::fcn_callback& fcn) + { + octave::event_manager& evmgr = m_interpreter.get_event_manager (); + + evmgr.post_event (fcn); + } + + void + qt_graphics_toolkit::interpreter_event (const octave::meth_callback& meth) + { + octave::event_manager& evmgr = m_interpreter.get_event_manager (); + + evmgr.post_event (meth); + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/graphics/qt-graphics-toolkit.h Fri Aug 02 12:18:48 2019 -0500 @@ -0,0 +1,94 @@ +/* + +Copyright (C) 2011-2019 Michael Goffioul + +This file is part of Octave. + +Octave is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Octave is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +<https://www.gnu.org/licenses/>. + +*/ + +#if ! defined (octave_qt_graphics_toolkit_h) +#define octave_qt_graphics_toolkit_h 1 + +#include <QObject> + +#include "event-manager.h" +#include "graphics.h" + +namespace octave +{ + class interpreter; +} + +namespace QtHandles +{ + class Object; + class ObjectFactory; + class ObjectProxy; + + class qt_graphics_toolkit : public QObject, public base_graphics_toolkit + { + Q_OBJECT + + public: + + qt_graphics_toolkit (octave::interpreter& interp); + + ~qt_graphics_toolkit (void); + + bool is_valid (void) const { return true; } + + void redraw_figure (const graphics_object& h) const; + + void show_figure (const graphics_object& h) const; + + void update (const graphics_object& obj, int pId); + + bool initialize (const graphics_object& obj); + + void finalize (const graphics_object& obj); + + void print_figure (const graphics_object& go, + const std::string& term, + const std::string& file_cmd, + const std::string& /*debug_file*/) const; + + uint8NDArray get_pixels (const graphics_object& go) const; + + Matrix get_text_extent (const graphics_object& go) const; + + static Object * toolkitObject (const graphics_object& go); + + static ObjectProxy * toolkitObjectProxy (const graphics_object& go); + + signals: + void createObject (qt_graphics_toolkit *, double handle); + + public slots: + + void interpreter_event (const octave::fcn_callback& fcn); + void interpreter_event (const octave::meth_callback& meth); + + private: + + octave::interpreter& m_interpreter; + + ObjectFactory *m_factory; + }; + +} + +#endif