1 //////////////////////////////////////////////////////////////////////// 2 // 3 // Copyright (C) 2011-2021 The Octave Project Developers 4 // 5 // See the file COPYRIGHT.md in the top-level directory of this 6 // distribution or <https://octave.org/copyright/>. 7 // 8 // This file is part of Octave. 9 // 10 // Octave is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 3 of the License, or 13 // (at your option) any later version. 14 // 15 // Octave is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Octave; see the file COPYING. If not, see 22 // <https://www.gnu.org/licenses/>. 23 // 24 //////////////////////////////////////////////////////////////////////// 25 26 #if defined (HAVE_CONFIG_H) 27 # include "config.h" 28 #endif 29 30 #include <QString> 31 #include <QVariant> 32 33 #include "Object.h" 34 #include "QtHandlesUtils.h" 35 #include "octave-qobject.h" 36 #include "qt-graphics-toolkit.h" 37 38 #include "graphics.h" 39 #include "interpreter.h" 40 41 namespace QtHandles 42 { 43 Object(octave::base_qobject & oct_qobj,octave::interpreter & interp,const graphics_object & go,QObject * obj)44 Object::Object (octave::base_qobject& oct_qobj, octave::interpreter& interp, 45 const graphics_object& go, QObject *obj) 46 : QObject (), m_octave_qobj (oct_qobj), m_interpreter (interp), 47 m_go (go), m_handle (go.get_handle ()), m_qobject (nullptr) 48 { 49 gh_manager& gh_mgr = m_interpreter.get_gh_manager (); 50 51 octave::autolock guard (gh_mgr.graphics_lock ()); 52 53 if (! guard) 54 qCritical ("QtHandles::Object::Object: " 55 "creating Object (h=%g) without a valid lock!!!", 56 m_handle.value ()); 57 58 init (obj); 59 } 60 61 void init(QObject * obj,bool)62 Object::init (QObject *obj, bool) 63 { 64 if (m_qobject) 65 qCritical ("QtHandles::Object::init: " 66 "resetting QObject while in invalid state"); 67 68 m_qobject = obj; 69 70 if (m_qobject) 71 { 72 m_qobject->setProperty ("QtHandles::Object", 73 QVariant::fromValue<void*> (this)); 74 connect (m_qobject, SIGNAL (destroyed (QObject*)), 75 SLOT (objectDestroyed (QObject*))); 76 } 77 } 78 ~Object(void)79 Object::~Object (void) 80 { } 81 82 graphics_object object(void) const83 Object::object (void) const 84 { 85 gh_manager& gh_mgr = m_interpreter.get_gh_manager (); 86 87 octave::autolock guard (gh_mgr.graphics_lock (), false); 88 89 if (! guard) 90 qCritical ("QtHandles::Object::object: " 91 "accessing graphics object (h=%g) without a valid lock!!!", 92 m_handle.value ()); 93 94 return m_go; 95 } 96 97 void slotUpdate(int pId)98 Object::slotUpdate (int pId) 99 { 100 gh_manager& gh_mgr = m_interpreter.get_gh_manager (); 101 102 octave::autolock guard (gh_mgr.graphics_lock ()); 103 104 switch (pId) 105 { 106 // Special case for objects being deleted, as it's very likely 107 // that the graphics_object already has been destroyed when this 108 // is executed (because of the async behavior). 109 case base_properties::ID_BEINGDELETED: 110 beingDeleted (); 111 break; 112 113 default: 114 if (object ().valid_object ()) 115 update (pId); 116 break; 117 } 118 } 119 120 void slotFinalize(void)121 Object::slotFinalize (void) 122 { 123 gh_manager& gh_mgr = m_interpreter.get_gh_manager (); 124 125 octave::autolock guard (gh_mgr.graphics_lock ()); 126 127 finalize (); 128 } 129 130 void slotRedraw(void)131 Object::slotRedraw (void) 132 { 133 gh_manager& gh_mgr = m_interpreter.get_gh_manager (); 134 135 octave::autolock guard (gh_mgr.graphics_lock ()); 136 137 if (object ().valid_object ()) 138 redraw (); 139 } 140 141 void slotShow(void)142 Object::slotShow (void) 143 { 144 gh_manager& gh_mgr = m_interpreter.get_gh_manager (); 145 146 octave::autolock guard (gh_mgr.graphics_lock ()); 147 148 if (object ().valid_object ()) 149 show (); 150 } 151 152 void slotPrint(const QString & file_cmd,const QString & term)153 Object::slotPrint (const QString& file_cmd, const QString& term) 154 { 155 gh_manager& gh_mgr = m_interpreter.get_gh_manager (); 156 157 octave::autolock guard (gh_mgr.graphics_lock ()); 158 159 if (object ().valid_object ()) 160 print (file_cmd, term); 161 } 162 163 void update(int)164 Object::update (int /* pId */) 165 { } 166 167 void finalize(void)168 Object::finalize (void) 169 { 170 if (m_qobject) 171 { 172 delete m_qobject; 173 m_qobject = nullptr; 174 } 175 deleteLater (); 176 } 177 178 void redraw(void)179 Object::redraw (void) 180 { } 181 182 void show(void)183 Object::show (void) 184 { } 185 186 void print(const QString &,const QString &)187 Object::print (const QString& /* file_cmd */, const QString& /* term */) 188 { } 189 190 void beingDeleted(void)191 Object::beingDeleted (void) 192 { } 193 objectDestroyed(QObject * obj)194 void Object::objectDestroyed (QObject *obj) 195 { 196 if (obj && obj == m_qobject) 197 m_qobject = nullptr; 198 } 199 200 Object* parentObject(octave::interpreter & interp,const graphics_object & go)201 Object::parentObject (octave::interpreter& interp, const graphics_object& go) 202 { 203 gh_manager& gh_mgr = interp.get_gh_manager (); 204 205 octave::autolock guard (gh_mgr.graphics_lock ()); 206 207 Object *parent = qt_graphics_toolkit::toolkitObject 208 (gh_mgr.get_object (go.get_parent ())); 209 210 return parent; 211 } 212 213 Object* fromQObject(QObject * obj)214 Object::fromQObject (QObject *obj) 215 { 216 QVariant v = obj->property ("QtHandles::Object"); 217 218 if (v.isValid ()) 219 return reinterpret_cast<Object *> (qvariant_cast<void*> (v)); 220 221 return nullptr; 222 } 223 224 void do_connections(const QObject * receiver,const QObject * emitter)225 Object::do_connections (const QObject *receiver, const QObject *emitter) 226 { 227 if (! emitter) 228 emitter = this; 229 230 connect (emitter, 231 SIGNAL (interpreter_event (const octave::fcn_callback&)), 232 receiver, 233 SLOT (interpreter_event (const octave::fcn_callback&))); 234 235 connect (emitter, 236 SIGNAL (interpreter_event (const octave::meth_callback&)), 237 receiver, 238 SLOT (interpreter_event (const octave::meth_callback&))); 239 240 connect (emitter, 241 SIGNAL (gh_callback_event (const graphics_handle&, 242 const std::string&)), 243 receiver, 244 SLOT (gh_callback_event (const graphics_handle&, 245 const std::string&))); 246 247 connect (emitter, 248 SIGNAL (gh_callback_event (const graphics_handle&, 249 const std::string&, 250 const octave_value&)), 251 receiver, 252 SLOT (gh_callback_event (const graphics_handle&, 253 const std::string&, 254 const octave_value&))); 255 256 connect (emitter, 257 SIGNAL (gh_set_event (const graphics_handle&, 258 const std::string&, 259 const octave_value&)), 260 receiver, 261 SLOT (gh_set_event (const graphics_handle&, 262 const std::string&, 263 const octave_value&))); 264 265 connect (emitter, 266 SIGNAL (gh_set_event (const graphics_handle&, 267 const std::string&, 268 const octave_value&, bool)), 269 receiver, 270 SLOT (gh_set_event (const graphics_handle&, 271 const std::string&, 272 const octave_value&, bool))); 273 274 connect (emitter, 275 SIGNAL (gh_set_event (const graphics_handle&, 276 const std::string&, 277 const octave_value&, 278 bool, bool)), 279 receiver, 280 SLOT (gh_set_event (const graphics_handle&, 281 const std::string&, 282 const octave_value&, 283 bool, bool))); 284 } 285 286 } 287