view libgui/graphics/Object.h @ 33571:742d8fc77688 default tip @

Support setting breakpoints in get and set methods of classdef properties (bug #65610). * cdef-class.cc (cdef_class::cdef_class_rep::get_method): Also check for any `get` or `set` methods of `classdef` properties. * bp-table.cc (user_code_provider::operator ()): Support getting (closest) user code to `get` or `set` methods of `classdef` classes. (user_code_provider::populate_function_cache): Add `get` and `set` methods to function cache for `classdef` classes. * pt-eval.cc (tree_evaluator::get_user_code): Support getting user code for `get` or `set` methods of `classdef` properties. * test/classdef-debug/classdef_breakpoints2.m: Add handle class with get and set methods for new self tests. * test/classdef-debug/test-classdef-breakpoints.tst: Add new tests for adding and clearing breakpoints in `set` and `get` methods of `classdef` properties by line number or function name. Make sure breakpoints are deleted in existing tests also on test failures. Fix syntax error in 69eb4c27d8c8. * test/classdef-debug/module.mk: Add new file to build system. * etc/NEWS.10.md: Add note about new feature.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 20 Apr 2024 13:13:50 +0200
parents 2e484f9f1f18
children
line wrap: on
line source

////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011-2024 The Octave Project Developers
//
// See the file COPYRIGHT.md in the top-level directory of this
// distribution or <https://octave.org/copyright/>.
//
// 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_Object_h)
#define octave_Object_h 1

#include <QObject>

#include "event-manager.h"
#include "graphics.h"

class QObject;
class QString;
class QWidget;

OCTAVE_BEGIN_NAMESPACE(octave)

class interpreter;

class Container;
class ObjectProxy;

class Object : public QObject
{
  Q_OBJECT

public:
  Object (octave::interpreter& interp, const graphics_object& go,
          QObject *obj = nullptr);

  virtual ~Object ();

  base_properties& properties ()
  { return object ().get_properties (); }

  const base_properties& properties () const
  { return object ().get_properties (); }

  template <typename T>
  typename T::properties& properties ()
  {
    return dynamic_cast<typename T::properties&>
           (object ().get_properties ());
  }

  template <typename T>
  const typename T::properties& properties () const
  {
    return dynamic_cast<const typename T::properties&>
           (object ().get_properties ());
  }

  graphics_object object () const;

  virtual QObject * qObject () { return m_qobject; }

  template <typename T>
  T * qWidget () { return qobject_cast<T *>(qObject ()); }

  virtual Container * innerContainer () = 0;

  static Object * fromQObject (QObject *obj);

  virtual void do_connections (const QObject *receiver,
                               const QObject *emitter = nullptr);

signals:

  void interpreter_event (const octave::fcn_callback& fcn);
  void interpreter_event (const octave::meth_callback& meth);

  void gh_callback_event (const graphics_handle& h, const std::string& name);

  void gh_callback_event (const graphics_handle& h, const std::string& name,
                          const octave_value& data);

  void gh_set_event (const graphics_handle& h, const std::string& name,
                     const octave_value& value);

  void gh_set_event (const graphics_handle& h, const std::string& name,
                     const octave_value& value, bool notify_toolkit);

  void gh_set_event (const graphics_handle& h, const std::string& name,
                     const octave_value& value, bool notify_toolkit,
                     bool redraw_figure);

public slots:
  void slotUpdate (int pId);
  void slotFinalize ();
  void slotRedraw ();
  void slotShow ();
  void slotPrint (const QString& file_cmd, const QString& term);

  void objectDestroyed (QObject *obj = nullptr);

protected:
  static Object *
  parentObject (octave::interpreter& interp, const graphics_object& go);

  void init (QObject *obj, bool callBase = false);

  virtual void update (int pId);
  virtual void finalize ();
  virtual void redraw ();
  virtual void show ();
  virtual void print (const QString& file_cmd, const QString& term);

  virtual void beingDeleted ();

protected:

  octave::interpreter& m_interpreter;

  // Store the graphics object directly so that it will exist when
  // we need it.  Previously, it was possible for the graphics
  // 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.
  // Also, the whole ObjectProxy thing may not need to store a
  // pointer now?  Maybe we can just have a lookup table from figure
  // handle to Object?  What does the FLTK toolkit do?  Why does
  // this seem to be so complicated?
  graphics_handle m_handle;

  QObject *m_qobject;
};

OCTAVE_END_NAMESPACE(octave)

#endif