# HG changeset patch # User John W. Eaton # Date 1572532783 14400 # Node ID ada24a1979c0ef53339b74d38f69e78043b6fa52 # Parent cf9fbfa04dd1cb432bf1efa452f93353262e117d improve thread safety of qt_interpreter_events::get_named_icon * qt-interpreter-events.h, qt-interpreter-events.cc (qt_interpreter_events::get_named_icon_result): New data member. (qt_interpreter_events::get_named_icon_signal): New signal (qt_interpreter_events::get_named_icon_slot): New slot to access resource_manager in GUI thread. (qt_interpreter_events::get_named_icon): Emit signal, wait for result, and perform QIcon to uint8NDArray conversion in interpreter thread. (qt_interpreter_events::qt_interpreter_events): Connect new signal and slot. diff -r cf9fbfa04dd1 -r ada24a1979c0 libgui/src/qt-interpreter-events.cc --- a/libgui/src/qt-interpreter-events.cc Thu Oct 31 09:59:35 2019 -0400 +++ b/libgui/src/qt-interpreter-events.cc Thu Oct 31 10:39:43 2019 -0400 @@ -117,6 +117,9 @@ connect (this, SIGNAL (confirm_shutdown_signal (void)), this, SLOT (confirm_shutdown_octave (void))); + + connect (this, SIGNAL (get_named_icon_signal (const QString&)), + this, SLOT (get_named_icon_slot (const QString&))); } std::list @@ -327,32 +330,58 @@ return retval; } - uint8NDArray qt_interpreter_events::get_named_icon (const std::string& icon_name) + uint8NDArray qt_interpreter_events::get_named_icon (const std::string& name) { - uint8NDArray retval; - QIcon icon = resource_manager::icon (QString::fromStdString (icon_name)); - if (! icon.isNull ()) + QMutexLocker autolock (&m_mutex); + + emit get_named_icon_signal (QString::fromStdString (name)); + + // Wait for result. + wait (); + + uint8NDArray empty_img; + + if (m_get_named_icon_result.isNull ()) + return empty_img; + + QImage img = m_get_named_icon_result.pixmap (QSize (32, 32)).toImage (); + + if (img.format () != QImage::Format_ARGB32_Premultiplied) + return empty_img; + + dim_vector dims (img.height (), img.width (), 4); + + uint8NDArray retval (dims, 0); + + uint8_t *bits = img.bits (); + + for (int i = 0; i < img.height (); i++) { - QImage img = icon.pixmap (QSize (32, 32)).toImage (); - - if (img.format () == QImage::Format_ARGB32_Premultiplied) + for (int j = 0; j < img.width (); j++) { - retval.resize (dim_vector (img.height (), img.width (), 4), 0); - uint8_t* bits = img.bits (); - for (int i = 0; i < img.height (); i++) - for (int j = 0; j < img.width (); j++) - { - retval(i,j,2) = bits[0]; - retval(i,j,1) = bits[1]; - retval(i,j,0) = bits[2]; - retval(i,j,3) = bits[3]; - bits += 4; - } + retval(i,j,2) = bits[0]; + retval(i,j,1) = bits[1]; + retval(i,j,0) = bits[2]; + retval(i,j,3) = bits[3]; + + bits += 4; } } + return retval; } + void qt_interpreter_events::get_named_icon_slot (const QString& name) + { + lock (); + + m_get_named_icon_result = resource_manager::icon (name); + + unlock (); + + wake_all (); + } + std::string qt_interpreter_events::gui_preference (const std::string& key, const std::string& value) diff -r cf9fbfa04dd1 -r ada24a1979c0 libgui/src/qt-interpreter-events.h --- a/libgui/src/qt-interpreter-events.h Thu Oct 31 09:59:35 2019 -0400 +++ b/libgui/src/qt-interpreter-events.h Thu Oct 31 10:39:43 2019 -0400 @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -180,6 +181,8 @@ void confirm_shutdown_octave (void); + void get_named_icon_slot (const QString& name); + signals: void copy_image_to_clipboard_signal (const QString& file, bool remove_file); @@ -234,6 +237,8 @@ void confirm_shutdown_signal (void); + void get_named_icon_signal (const QString& name); + private: void insert_debugger_pointer (const std::string& file, int line); @@ -244,6 +249,8 @@ bool m_shutdown_confirm_result; + QIcon m_get_named_icon_result; + QMutex m_mutex; QWaitCondition m_waitcondition;