From 01959690cd1f0da50b9f5285b11ec9b65e46a0a9 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Wed, 22 Nov 2023 21:19:36 +0100 Subject: [PATCH 001/257] Get rid of member variable declaration in wxWindowDC under wxQt This is harmful because it hides the variable declared in the base class and as a result, GetWindow() will always return nullptr. --- include/wx/qt/dcclient.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/wx/qt/dcclient.h b/include/wx/qt/dcclient.h index 76dd03e15e..df94a595d8 100644 --- a/include/wx/qt/dcclient.h +++ b/include/wx/qt/dcclient.h @@ -22,9 +22,6 @@ public: ~wxWindowDCImpl(); -protected: - wxWindow *m_window; - private: wxDECLARE_CLASS(wxWindowDCImpl); wxDECLARE_NO_COPY_CLASS(wxWindowDCImpl); From 41e9fc9a9ad0acc5631f8651e40cd2e3774b356c Mon Sep 17 00:00:00 2001 From: ali kettab Date: Wed, 22 Nov 2023 23:04:15 +0100 Subject: [PATCH 002/257] Fix wxClientDC not working under wxQt The problem was: wxClientDC draws in a QPicture owned by the DC. In the destructor, QtPictureSetter sets the picture to be used by the associated window and generates a paint event, then resets the picture when it goes out of scope before the paint handler has a chance to replay the image. In this commit, this setup is changed so that window owns the picture instead and is responsible for deleting it when it is actually used. --- include/wx/qt/window.h | 4 +-- src/qt/dcclient.cpp | 63 ++++++++++++------------------------------ src/qt/window.cpp | 7 ++--- 3 files changed, 22 insertions(+), 52 deletions(-) diff --git a/include/wx/qt/window.h b/include/wx/qt/window.h index 17cc930fa9..acbd9b6fce 100644 --- a/include/wx/qt/window.h +++ b/include/wx/qt/window.h @@ -152,7 +152,7 @@ public: // wxQt implementation internals: - // Caller maintains ownership of pict - window will NOT delete it + // Takes ownership of pict - window will delete it void QtSetPicture( QPicture* pict ); QPainter *QtGetPainter(); @@ -244,7 +244,7 @@ private: bool QtSetBackgroundStyle(); - QPicture *m_qtPicture; // not owned + std::unique_ptr m_qtPicture; // owned by this window std::unique_ptr m_qtPainter; // always allocated bool m_mouseInside; diff --git a/src/qt/dcclient.cpp b/src/qt/dcclient.cpp index f0894ef192..4f80566859 100644 --- a/src/qt/dcclient.cpp +++ b/src/qt/dcclient.cpp @@ -18,36 +18,13 @@ #include "wx/dcclient.h" #include "wx/qt/dcclient.h" +#include "wx/qt/private/converter.h" #include #include //############################################################################## -namespace -{ -class QtPictureSetter -{ -public: - QtPictureSetter(wxWindow *window, QPicture *pict) - : m_window( window ) - { - m_window->QtSetPicture( pict ); - } - - ~QtPictureSetter() - { - m_window->QtSetPicture( nullptr ); - } - -private: - wxWindow* const m_window; - - wxDECLARE_NO_COPY_CLASS(QtPictureSetter); -}; -} - - wxIMPLEMENT_CLASS(wxWindowDCImpl,wxQtDCImpl); wxWindowDCImpl::wxWindowDCImpl( wxDC *owner ) @@ -110,30 +87,24 @@ wxClientDCImpl::~wxClientDCImpl() m_qtPainter->end(); m_ok = false; - if ( m_window != nullptr ) + if ( m_window ) { - QtPictureSetter pictureSetter(m_window, m_pict.get()); - - // get the inner widget in scroll areas: - QWidget *widget; - if ( m_window->QtGetScrollBarsContainer() ) + if ( m_pict && !m_pict->isNull() ) { - widget = m_window->QtGetScrollBarsContainer()->viewport(); - } else { - widget = m_window->GetHandle(); - } - // force paint event if there is something to replay and - // if not currently inside a paint event (to avoid recursion) - QRect rect = m_pict->boundingRect(); - if ( !m_pict->isNull() && !widget->paintingActive() && !rect.isEmpty() ) - { - // only force the update of the rect affected by the DC - widget->update( rect ); - } - else - { - // Not drawing anything, reset picture to avoid issues in handler - m_pict->setData( nullptr, 0 ); + // force paint event if there is something to replay and + // if not currently inside a paint event (to avoid recursion) + wxRect rect = wxQtConvertRect(m_pict->boundingRect()); + if ( !m_window->GetHandle()->paintingActive() && !rect.IsEmpty() ) + { + m_window->QtSetPicture( m_pict.release() ); + // only force the update of the rect affected by the DC + m_window->Refresh(true, &rect); + } + else // Do we really need the else branch? we are in the dtor anyhow! + { + // Not drawing anything, reset picture to avoid issues in handler + m_pict.reset(); + } } // let destroy the m_qtPainter (see inherited classes destructors) diff --git a/src/qt/window.cpp b/src/qt/window.cpp index 4a94d5082c..4c4d7febf7 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -276,7 +276,6 @@ void wxWindowQt::Init() m_horzScrollBar = nullptr; m_vertScrollBar = nullptr; - m_qtPicture = nullptr; m_qtPainter.reset(new QPainter()); m_mouseInside = false; @@ -1315,7 +1314,7 @@ bool wxWindowQt::QtHandlePaintEvent ( QWidget *handler, QPaintEvent *event ) { bool handled; - if ( m_qtPicture == nullptr ) + if ( !m_qtPicture ) { // Real paint event (not for wxClientDC), prepare the background switch ( GetBackgroundStyle() ) @@ -1382,7 +1381,7 @@ bool wxWindowQt::QtHandlePaintEvent ( QWidget *handler, QPaintEvent *event ) // Data from wxClientDC, paint it m_qtPicture->play( m_qtPainter.get() ); // Reset picture - m_qtPicture->setData( nullptr, 0 ); + m_qtPicture.reset(); handled = true; } @@ -1788,7 +1787,7 @@ QScrollArea *wxWindowQt::QtGetScrollBarsContainer() const void wxWindowQt::QtSetPicture( QPicture* pict ) { - m_qtPicture = pict; + m_qtPicture.reset(pict); } QPainter *wxWindowQt::QtGetPainter() From 0c6e2fafd6b65830aa72e3890011186fd6e737e1 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 23 Nov 2023 22:48:05 +0100 Subject: [PATCH 003/257] Make wxWindowDC work if constructed outside of a paint event under wxQt Also prepare wxScreenDC to work with wxOverlay (in the upcoming commit) --- include/wx/qt/dcclient.h | 12 ++++-- src/qt/dcclient.cpp | 91 +++++++++++++++++++--------------------- src/qt/dcscreen.cpp | 10 ++++- 3 files changed, 58 insertions(+), 55 deletions(-) diff --git a/include/wx/qt/dcclient.h b/include/wx/qt/dcclient.h index df94a595d8..788c4867ba 100644 --- a/include/wx/qt/dcclient.h +++ b/include/wx/qt/dcclient.h @@ -22,6 +22,12 @@ public: ~wxWindowDCImpl(); +protected: + std::unique_ptr m_pict; + + // @true if m_qtPainter is owned by the window, @false otherwise (default). + bool m_isWindowPainter = false; + private: wxDECLARE_CLASS(wxWindowDCImpl); wxDECLARE_NO_COPY_CLASS(wxWindowDCImpl); @@ -34,20 +40,18 @@ public: wxClientDCImpl( wxDC *owner ); wxClientDCImpl( wxDC *owner, wxWindow *win ); - ~wxClientDCImpl(); private: - std::unique_ptr m_pict; - wxDECLARE_CLASS(wxClientDCImpl); wxDECLARE_NO_COPY_CLASS(wxClientDCImpl); }; -class WXDLLIMPEXP_CORE wxPaintDCImpl : public wxWindowDCImpl +class WXDLLIMPEXP_CORE wxPaintDCImpl : public wxClientDCImpl { public: wxPaintDCImpl( wxDC *owner ); wxPaintDCImpl( wxDC *owner, wxWindow *win ); + private: wxDECLARE_CLASS(wxPaintDCImpl); wxDECLARE_NO_COPY_CLASS(wxPaintDCImpl); diff --git a/src/qt/dcclient.cpp b/src/qt/dcclient.cpp index 4f80566859..c4f9a23a6e 100644 --- a/src/qt/dcclient.cpp +++ b/src/qt/dcclient.cpp @@ -39,53 +39,32 @@ wxWindowDCImpl::wxWindowDCImpl( wxDC *owner, wxWindow *win ) : wxQtDCImpl( owner ) { m_window = win; - m_qtPainter = m_window->QtGetPainter(); - // if we're not inside a Paint event, painter will invalid - m_ok = m_qtPainter != nullptr; + m_qtPainter = m_window->QtGetPainter(); // guaranteed to be non-null + + if ( m_qtPainter->isActive() ) + { + m_isWindowPainter = true; + } + else + { + m_qtPainter = new QPainter(); + m_pict.reset( new QPicture() ); + m_ok = m_qtPainter->begin( m_pict.get() ); + QtPreparePainter(); + } } wxWindowDCImpl::~wxWindowDCImpl() -{ - if ( m_ok ) - { - m_ok = false; - } - if ( m_window ) - { - // do not destroy in base class as it is owned by the window - m_qtPainter = nullptr; - } -} - -//############################################################################## - -wxIMPLEMENT_CLASS(wxClientDCImpl,wxWindowDCImpl); - -wxClientDCImpl::wxClientDCImpl( wxDC *owner ) - : wxWindowDCImpl( owner ) -{ -} - -wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *win ) - : wxWindowDCImpl( owner ) -{ - m_window = win; - - m_pict.reset(new QPicture()); - m_ok = m_qtPainter->begin( m_pict.get() ); - - QtPreparePainter(); -} - -wxClientDCImpl::~wxClientDCImpl() { /* Paint to a QPicture that will then be painted in the next * paint event of that window (a paint event will be generated * when this wxClientDC is done). */ if ( m_ok ) { - m_qtPainter->end(); - m_ok = false; + if ( m_isWindowPainter ) + m_qtPainter = nullptr; // do not destroy in base class as it is owned by the window + else + m_qtPainter->end(); if ( m_window ) { @@ -112,28 +91,42 @@ wxClientDCImpl::~wxClientDCImpl() } } - // Painter will be deleted by base class + // Painter will be deleted by base class if we own it } +//############################################################################## + +wxIMPLEMENT_CLASS(wxClientDCImpl,wxWindowDCImpl); + +wxClientDCImpl::wxClientDCImpl( wxDC *owner ) + : wxWindowDCImpl( owner ) +{ +} + +wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *win ) + : wxWindowDCImpl( owner, win ) +{ + if ( m_ok ) + { + m_qtPainter->setClipRect( wxQtConvertRect(win->GetClientRect()), + m_clipping ? Qt::IntersectClip : Qt::ReplaceClip ); + } +} + + //############################################################################## wxIMPLEMENT_CLASS(wxPaintDCImpl,wxClientDCImpl); wxPaintDCImpl::wxPaintDCImpl( wxDC *owner ) - : wxWindowDCImpl( owner ) + : wxClientDCImpl( owner ) { - if ( m_ok ) - { - QtPreparePainter(); - } } wxPaintDCImpl::wxPaintDCImpl( wxDC *owner, wxWindow *win ) - : wxWindowDCImpl( owner, win ) + : wxClientDCImpl( owner, win ) { - if ( m_ok ) - { - QtPreparePainter(); - } + wxCHECK_RET( m_isWindowPainter, + "wxPaintDC can't be created outside wxEVT_PAINT handler" ); } diff --git a/src/qt/dcscreen.cpp b/src/qt/dcscreen.cpp index 1f08768ec0..60a71fcf55 100644 --- a/src/qt/dcscreen.cpp +++ b/src/qt/dcscreen.cpp @@ -11,16 +11,22 @@ #include "wx/dcscreen.h" #include "wx/qt/dcscreen.h" -#include -#include #include +#include +#include +#include #include +#include wxIMPLEMENT_ABSTRACT_CLASS(wxScreenDCImpl, wxQtDCImpl); wxScreenDCImpl::wxScreenDCImpl( wxScreenDC *owner ) : wxWindowDCImpl( owner ) { + m_pict.reset(new QPicture()); + m_ok = m_qtPainter->begin( m_pict.get() ); + + QtPreparePainter(); } wxScreenDCImpl::~wxScreenDCImpl( ) From d205e331cef972a09b2f811529cc97ae3f7bce77 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 23 Nov 2023 19:03:11 +0100 Subject: [PATCH 004/257] Added native wxOverlay implementation under wxQt --- Makefile.in | 24 +++++- build/bakefiles/files.bkl | 1 + build/cmake/files.cmake | 1 + build/files | 1 + include/wx/private/overlay.h | 2 + src/qt/overlay.cpp | 145 +++++++++++++++++++++++++++++++++++ 6 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 src/qt/overlay.cpp diff --git a/Makefile.in b/Makefile.in index 532042fe8f..b3ec7f4260 100644 --- a/Makefile.in +++ b/Makefile.in @@ -5534,7 +5534,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS = \ monodll_qt_treectrl.o \ monodll_paletteg.o \ monodll_qt_datectrl.o \ - monodll_qt_timectrl.o + monodll_qt_timectrl.o \ + monodll_qt_overlay.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS) @COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS = \ @COND_PLATFORM_UNIX_1@ monodll_unix_dialup.o monodll_unix_joystick.o \ @@ -7297,7 +7298,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_1 = \ monolib_qt_treectrl.o \ monolib_paletteg.o \ monolib_qt_datectrl.o \ - monolib_qt_timectrl.o + monolib_qt_timectrl.o \ + monolib_qt_overlay.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_1 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_1) @COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS_1 = \ @COND_PLATFORM_UNIX_1@ monolib_unix_dialup.o monolib_unix_joystick.o \ @@ -9212,7 +9214,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_2 = \ coredll_qt_treectrl.o \ coredll_paletteg.o \ coredll_qt_datectrl.o \ - coredll_qt_timectrl.o + coredll_qt_timectrl.o \ + coredll_qt_overlay.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_2 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_2) @COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS_2 = \ @COND_PLATFORM_UNIX_1@ coredll_unix_dialup.o coredll_unix_joystick.o \ @@ -10703,7 +10706,8 @@ COND_TOOLKIT_QT___GUI_SRC_OBJECTS_3 = \ corelib_qt_treectrl.o \ corelib_paletteg.o \ corelib_qt_datectrl.o \ - corelib_qt_timectrl.o + corelib_qt_timectrl.o \ + corelib_qt_overlay.o @COND_TOOLKIT_QT@__GUI_SRC_OBJECTS_3 = $(COND_TOOLKIT_QT___GUI_SRC_OBJECTS_3) @COND_PLATFORM_UNIX_1@__QT_PLATFORM_SRC_OBJECTS_3 = \ @COND_PLATFORM_UNIX_1@ corelib_unix_dialup.o corelib_unix_joystick.o \ @@ -15802,6 +15806,9 @@ monodll_qt_datectrl.o: $(srcdir)/src/qt/datectrl.cpp $(MONODLL_ODEP) monodll_qt_timectrl.o: $(srcdir)/src/qt/timectrl.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/timectrl.cpp +monodll_qt_overlay.o: $(srcdir)/src/qt/overlay.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/qt/overlay.cpp + monodll_mdig.o: $(srcdir)/src/generic/mdig.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp @@ -20545,6 +20552,9 @@ monolib_qt_datectrl.o: $(srcdir)/src/qt/datectrl.cpp $(MONOLIB_ODEP) monolib_qt_timectrl.o: $(srcdir)/src/qt/timectrl.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/timectrl.cpp +monolib_qt_overlay.o: $(srcdir)/src/qt/overlay.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/qt/overlay.cpp + monolib_mdig.o: $(srcdir)/src/generic/mdig.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp @@ -25966,6 +25976,9 @@ coredll_qt_datectrl.o: $(srcdir)/src/qt/datectrl.cpp $(COREDLL_ODEP) coredll_qt_timectrl.o: $(srcdir)/src/qt/timectrl.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/timectrl.cpp +coredll_qt_overlay.o: $(srcdir)/src/qt/overlay.cpp $(COREDLL_ODEP) + $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/qt/overlay.cpp + coredll_mdig.o: $(srcdir)/src/generic/mdig.cpp $(COREDLL_ODEP) $(CXXC) -c -o $@ $(COREDLL_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp @@ -29683,6 +29696,9 @@ corelib_qt_datectrl.o: $(srcdir)/src/qt/datectrl.cpp $(CORELIB_ODEP) corelib_qt_timectrl.o: $(srcdir)/src/qt/timectrl.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/timectrl.cpp +corelib_qt_overlay.o: $(srcdir)/src/qt/overlay.cpp $(CORELIB_ODEP) + $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/qt/overlay.cpp + corelib_mdig.o: $(srcdir)/src/generic/mdig.cpp $(CORELIB_ODEP) $(CXXC) -c -o $@ $(CORELIB_CXXFLAGS) $(srcdir)/src/generic/mdig.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 584d4539f9..ec7c3637fc 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -477,6 +477,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/generic/paletteg.cpp src/qt/datectrl.cpp src/qt/timectrl.cpp + src/qt/overlay.cpp diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index b66b6cb20a..d04334668e 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -390,6 +390,7 @@ set(QT_SRC src/generic/paletteg.cpp src/qt/datectrl.cpp src/qt/timectrl.cpp + src/qt/overlay.cpp ) set(MEDIA_QT_SRC diff --git a/build/files b/build/files index 278120c6f0..a25c420544 100644 --- a/build/files +++ b/build/files @@ -379,6 +379,7 @@ QT_SRC= src/qt/msgdlg.cpp src/qt/nonownedwnd.cpp src/qt/notebook.cpp + src/qt/overlay.cpp src/qt/pen.cpp src/qt/popupwin.cpp src/qt/printdlg.cpp diff --git a/include/wx/private/overlay.h b/include/wx/private/overlay.h index fc95d53722..fed674b014 100644 --- a/include/wx/private/overlay.h +++ b/include/wx/private/overlay.h @@ -21,6 +21,8 @@ #elif defined(__WXGTK3__) #define wxHAS_NATIVE_OVERLAY 1 #define wxHAS_GENERIC_OVERLAY 1 +#elif defined(__WXQT__) + #define wxHAS_NATIVE_OVERLAY 1 #else #define wxHAS_GENERIC_OVERLAY 1 #endif diff --git a/src/qt/overlay.cpp b/src/qt/overlay.cpp new file mode 100644 index 0000000000..1807bd02b1 --- /dev/null +++ b/src/qt/overlay.cpp @@ -0,0 +1,145 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: src/qt/overlay.cpp +// Author: Ali Kettab +// Created: 2023-11-01 +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#include "wx/wxprec.h" + +#ifdef __WXQT__ + +#include "wx/private/overlay.h" +#include "wx/dc.h" +#include "wx/window.h" + +#include +#include +#include +#include +#include + +// Inspired by QRubberBand implementation + +class wxOverlayWindow : public QWidget +{ +public: + explicit wxOverlayWindow(QWidget* parent) + : QWidget(parent, parent ? Qt::Widget : Qt::ToolTip) + { + if ( !parent ) + setAttribute(Qt::WA_TranslucentBackground); + setAttribute(Qt::WA_TransparentForMouseEvents); + setAttribute(Qt::WA_NoSystemBackground); + setAttribute(Qt::WA_WState_ExplicitShowHide); + setVisible(false); + } + + void SetPicture(QPicture& pict) + { + m_pict.swap(pict); + update(); + } + +private: + + QPicture m_pict; + + virtual void paintEvent(QPaintEvent* WXUNUSED(event)) override + { + QPainter painter(this); + m_pict.play(&painter); + } +}; + +class wxOverlayImpl: public wxOverlay::Impl +{ +public: + wxOverlayImpl() = default; + ~wxOverlayImpl(); + + virtual bool IsOk() override; + virtual void Init(wxDC*, int, int, int, int) override; + virtual void BeginDrawing(wxDC* dc) override; + virtual void EndDrawing(wxDC* dc) override; + virtual void Clear(wxDC* dc) override; + virtual void Reset() override; + + wxWindow* m_target = nullptr; + wxOverlayWindow* m_overlay = nullptr; +}; + +wxOverlay::Impl* wxOverlay::Create() +{ + return new wxOverlayImpl; +} + + +wxOverlayImpl::~wxOverlayImpl() +{ + if ( m_target && !m_target->IsBeingDeleted() ) + { + if ( m_overlay ) + wxDELETE(m_overlay); + } +} + +bool wxOverlayImpl::IsOk() +{ + return m_overlay != nullptr; +} + +void wxOverlayImpl::Init(wxDC* dc, int , int , int , int ) +{ + wxASSERT_MSG( !IsOk() , "You cannot Init an overlay twice" ); + + wxCHECK_RET( dc, "Invalid dc for wxOverlay" ); + + m_target = dc->GetWindow(); + + m_overlay = new wxOverlayWindow(m_target ? m_target->GetHandle() : nullptr); +} + +void wxOverlayImpl::BeginDrawing(wxDC* WXUNUSED(dc)) +{ + wxCHECK_RET( IsOk(), "wxOverlay not initialized" ); + + QRect qtRect = m_target ? m_target->GetHandle()->rect() + : qGuiApp->primaryScreen()->geometry(); + + m_overlay->setGeometry( qtRect ); + m_overlay->show(); + m_overlay->raise(); +} + +void wxOverlayImpl::EndDrawing(wxDC* dc) +{ + wxCHECK_RET( dc, "Invalid dc for wxOverlay" ); + + auto painter = static_cast(dc->GetHandle()); + auto picture = dynamic_cast(painter->device()); + + if ( picture && !picture->isNull() ) + { + // take over the picture and draw it on the overlay window + m_overlay->SetPicture(*picture); + } +} + +void wxOverlayImpl::Clear(wxDC* WXUNUSED(dc)) +{ + // Already cleared by wxQt +} + +void wxOverlayImpl::Reset() +{ + if ( m_overlay ) + { + if ( m_target ) + m_overlay->hide(); + else + wxDELETE(m_overlay); + } +} + +#endif // __WXQT__ From 308f16d97bd91391f9ae3ba5a9716f8415e2b5e8 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 23 Nov 2023 19:18:20 +0100 Subject: [PATCH 005/257] Fix caret sample under wxQt wxQt has the same issue as wxOSX fixed here 21e02d5 (render characters on OSX one by one as fractional widths leads to errors otherwise) --- samples/caret/caret.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/samples/caret/caret.cpp b/samples/caret/caret.cpp index 44e9f6177a..7e4d268506 100644 --- a/samples/caret/caret.cpp +++ b/samples/caret/caret.cpp @@ -419,7 +419,7 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxChar ch = CharAt(x, y); if ( !ch ) ch = ' '; -#ifdef __WXOSX__ +#if defined(__WXOSX__) || defined(__WXQT__) dc.DrawText(ch, m_xMargin + x * m_widthChar, m_yMargin + y * m_heightChar ); #else @@ -427,9 +427,8 @@ void MyCanvas::OnPaint( wxPaintEvent &WXUNUSED(event) ) #endif } -#ifndef __WXOSX__ - dc.DrawText( line, m_xMargin, m_yMargin + y * m_heightChar ); -#endif + if ( !line.empty() ) + dc.DrawText( line, m_xMargin, m_yMargin + y * m_heightChar ); } } From 2ddfcc2b2830bafa096b4830bf915c1cdefeb816 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Fri, 1 Dec 2023 12:36:35 -0800 Subject: [PATCH 006/257] Remove wxTextCtrl frame with wxBORDER_NONE for GTK3 This was deleted for GTK3 in 80e2264373 (Fix wxBORDER_NONE handling for wxTextCtrl under GTK+ 3, 2017-10-31), but there was no harm in keeping it, and it actually helps with a transitory visual glitch when the widget is created on a parent that is already showing. See #24105 --- src/gtk/textctrl.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 41e5279bd3..6fad82910c 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -797,11 +797,8 @@ bool wxTextCtrl::Create( wxWindow *parent, // new, empty control, see https://github.com/wxWidgets/wxWidgets/issues/11409 gtk_entry_get_text((GtkEntry*)m_text); -#ifndef __WXGTK3__ if (style & wxNO_BORDER) gtk_entry_set_has_frame((GtkEntry*)m_text, FALSE); -#endif - } g_object_ref(m_widget); From d8b2fc108065b2da4f875e9695a6cc2ec203c872 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Sat, 2 Dec 2023 15:26:45 -0800 Subject: [PATCH 007/257] Avoid refreshing a rect with a negative size --- src/generic/grid.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index fec78cd1f6..31ca624bbb 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -9905,8 +9905,11 @@ void wxGrid::DoSetRowSize( int row, int height ) int cw, ch; GetClientSize(&cw, &ch); - const wxRect updateRect(0, y, cw, ch - y); - Refresh(true, &updateRect); + if (ch > y) + { + const wxRect updateRect(0, y, cw, ch - y); + Refresh(true, &updateRect); + } } } @@ -10046,8 +10049,11 @@ void wxGrid::DoSetColSize( int col, int width ) int cw, ch; GetClientSize(&cw, &ch); - const wxRect updateRect(x, 0, cw - x, ch); - Refresh(true, &updateRect); + if (cw > x) + { + const wxRect updateRect(x, 0, cw - x, ch); + Refresh(true, &updateRect); + } } } From 54ed3abdad3861d90303b8b46334fd46c90f7cac Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Sat, 2 Dec 2023 15:36:39 -0800 Subject: [PATCH 008/257] Avoid size-allocating invisible widgets Avoids Gtk-CRITICAL gtk_widget_set_allocation: assertion '_gtk_widget_get_visible (widget) || _gtk_widget_is_toplevel (widget)' failed --- src/gtk/win_gtk.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gtk/win_gtk.cpp b/src/gtk/win_gtk.cpp index 12dca59764..7c3d768553 100644 --- a/src/gtk/win_gtk.cpp +++ b/src/gtk/win_gtk.cpp @@ -458,6 +458,9 @@ struct AdjustData { extern "C" { static void scroll_adjust(GtkWidget* widget, void* data) { + if (!gtk_widget_get_visible(widget)) + return; + const AdjustData* p = static_cast(data); GtkAllocation a; gtk_widget_get_allocation(widget, &a); From 6f62907cae65f46c71dfdca33ed84c0e50fb7408 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Sat, 2 Dec 2023 16:08:46 -0800 Subject: [PATCH 009/257] Avoid setting a negative window size --- src/propgrid/manager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/propgrid/manager.cpp b/src/propgrid/manager.cpp index 01e16ffa70..e4e3d33de1 100644 --- a/src/propgrid/manager.cpp +++ b/src/propgrid/manager.cpp @@ -1454,8 +1454,8 @@ void wxPropertyGridManager::RepaintDescBoxDecorations( wxDC& dc, void wxPropertyGridManager::UpdateDescriptionBox( int new_splittery, int new_width, int new_height ) { - int use_hei = new_height-1; - int use_width = new_width-6; + int use_hei = wxMax(1, new_height - 1); + int use_width = wxMax(1, new_width - 6); // Fix help control positions. int cap_y = new_splittery+m_splitterHeight+5; From d62fafe847416034ae35259551a575c357b5ea29 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sat, 2 Dec 2023 18:12:12 -0500 Subject: [PATCH 010/257] Add wxNativeContainerWindow to wxTopLevelWindows list This ensures that wxDialog::ShowModal() disables wxNativeContainerWindow too. Closes #24112. --- src/msw/nativewin.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/msw/nativewin.cpp b/src/msw/nativewin.cpp index c166f3e04e..a4f10d7bdc 100644 --- a/src/msw/nativewin.cpp +++ b/src/msw/nativewin.cpp @@ -111,6 +111,8 @@ bool wxNativeContainerWindow::Create(wxNativeContainerWindowHandle hwnd) // inherit the other attributes we can from the native HWND AdoptAttributesFromHWND(); + wxTopLevelWindows.Append(this); + return true; } From 11ed91af8fc79f0a3d41a7c6b0a9b1c447b54598 Mon Sep 17 00:00:00 2001 From: Kumazuma Date: Sun, 3 Dec 2023 13:19:10 +0900 Subject: [PATCH 011/257] Add missing default constructor of wxFileDialog in wxMSW This ctor exists in the other ports and there is no reason for it not to exist in wxMSW too. Closes #24113. --- include/wx/msw/filedlg.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/wx/msw/filedlg.h b/include/wx/msw/filedlg.h index 6a01c8356b..090c3e2418 100644 --- a/include/wx/msw/filedlg.h +++ b/include/wx/msw/filedlg.h @@ -19,6 +19,7 @@ class wxFileDialogMSWData; class WXDLLIMPEXP_CORE wxFileDialog: public wxFileDialogBase { public: + wxFileDialog() = default; wxFileDialog(wxWindow *parent, const wxString& message = wxASCII_STR(wxFileSelectorPromptStr), const wxString& defaultDir = wxEmptyString, From ed02e035850202fa277d426f0537f05bdfc8fbee Mon Sep 17 00:00:00 2001 From: Martin Corino Date: Thu, 30 Nov 2023 20:41:42 +0100 Subject: [PATCH 012/257] Make wxEL_ALLOW_NEW imply wxEL_ALLOW_EDIT in wxEditableListBox Without this change, using wxEL_ALLOW_NEW without wxEL_ALLOW_EDIT resulted in an assertion failure, so fix it by turning wxEL_ALLOW_EDIT too in this case: this makes sense because adding a new element is "editing" too, and there doesn't seem to be any realistic scenario in which new items can be added but the existing items can't be changed. Closes #24099. Closes #24100. --- interface/wx/editlbox.h | 2 +- src/generic/editlbox.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/interface/wx/editlbox.h b/interface/wx/editlbox.h index 80462b24dc..445e60012c 100644 --- a/interface/wx/editlbox.h +++ b/interface/wx/editlbox.h @@ -19,7 +19,7 @@ @beginStyleTable @style{wxEL_ALLOW_NEW} - Allows the user to enter new strings. + Allows the user to enter new strings (implies wxEL_ALLOW_EDIT as well). @style{wxEL_ALLOW_EDIT} Allows the user to edit existing strings. @style{wxEL_ALLOW_DELETE} diff --git a/src/generic/editlbox.cpp b/src/generic/editlbox.cpp index 5f040ef227..641e541641 100644 --- a/src/generic/editlbox.cpp +++ b/src/generic/editlbox.cpp @@ -113,6 +113,10 @@ bool wxEditableListBox::Create(wxWindow *parent, wxWindowID id, m_style = style; + // wxEL_ALLOW_NEW requires ability to edit labels so implicitly add wxEL_ALLOW_EDIT + if ( m_style & wxEL_ALLOW_NEW ) + m_style |= wxEL_ALLOW_EDIT; + wxSizer *sizer = new wxBoxSizer(wxVERTICAL); wxPanel *subp = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, @@ -167,7 +171,7 @@ bool wxEditableListBox::Create(wxWindow *parent, wxWindowID id, sizer->Add(subp, wxSizerFlags().Expand()); long st = wxLC_REPORT | wxLC_NO_HEADER | wxLC_SINGLE_SEL | wxSUNKEN_BORDER; - if ( style & wxEL_ALLOW_EDIT ) + if ( m_style & wxEL_ALLOW_EDIT ) st |= wxLC_EDIT_LABELS; m_listCtrl = new CleverListCtrl(this, wxID_ELB_LISTCTRL, wxDefaultPosition, wxDefaultSize, st); From 2c9fee3d6fe4a55f6a8b3528a5f9c18dabc7530c Mon Sep 17 00:00:00 2001 From: ali kettab Date: Sun, 26 Nov 2023 01:38:40 +0100 Subject: [PATCH 013/257] Add wxStatusBar::AddFieldControl() to simplify adding controls This allows user codes to simply designate where their controls should appear in the status bar without the need to handle wxEVT_SIZE themselves. They can still handle the event if the default positioning does not meet their needs, but the new API is simpler and can be implemented for wxQt. Closes #24092. --- include/wx/statusbr.h | 20 +++++++++++++++++++ interface/wx/statusbr.h | 16 ++++++++++++++++ samples/statbar/statbar.cpp | 21 ++------------------ src/common/statbar.cpp | 38 +++++++++++++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 19 deletions(-) diff --git a/include/wx/statusbr.h b/include/wx/statusbr.h index f27a225dcb..8a4506a8d4 100644 --- a/include/wx/statusbr.h +++ b/include/wx/statusbr.h @@ -17,6 +17,7 @@ #include "wx/control.h" #include "wx/list.h" #include "wx/dynarray.h" +#include "wx/weakref.h" extern WXDLLIMPEXP_DATA_CORE(const char) wxStatusBarNameStr[]; @@ -84,6 +85,11 @@ public: // really restored anything bool PopText(); + // set/get the control (child of the wxStatusBar) that will be shown in + // this pane. + void SetFieldControl(wxWindow* win) { m_control = win; } + wxWindow* GetFieldControl() const { return m_control; } + private: int m_nStyle; int m_nWidth; // may be negative, indicating a variable-width field @@ -97,6 +103,9 @@ private: // is the currently shown value shown with ellipsis in the status bar? bool m_bEllipsized; + + // remember the control that will be shown in this pane. Updated by SetFieldControl(). + wxWindowRef m_control; }; // This is preserved for compatibility, but is not supposed to be used by the @@ -173,6 +182,14 @@ public: wxSize GetBorders() const { return wxSize(GetBorderX(), GetBorderY()); } + // controls + // -------- + + // Add a control (child of the wxStatusBar) to be shown at the specified + // field position #n. Note that you must delete the control to remove it + // from the status bar, as simply passing _nullptr_ will not do that. + bool AddFieldControl(int n, wxWindow* win); + // miscellaneous // ------------- @@ -192,6 +209,9 @@ protected: // display virtual void DoUpdateStatusText(int number) = 0; + // Position the added controls (added by AddFieldControl()), if any, in + // their corresponding destination. + void OnSize(wxSizeEvent& event); // wxWindow overrides: diff --git a/interface/wx/statusbr.h b/interface/wx/statusbr.h index 2d25722607..0e93b92a3f 100644 --- a/interface/wx/statusbr.h +++ b/interface/wx/statusbr.h @@ -248,6 +248,22 @@ public: */ virtual void SetFieldsCount(int number = 1, const int* widths = nullptr); + /** + Add a control (child of the wxStatusBar) to be shown at the specified + field position in the status bar. + + @param i + The field index where the control will be shown. + @param win + The control in question. Must be a child of the wxStatusBar itself. + + @note You must delete the control to remove it from the status bar, as + simply passing @NULL will not do that. + + @since 3.3.0 + */ + bool AddFieldControl(int i, wxWindow* win); + /** Sets the minimal possible height for the status bar. diff --git a/samples/statbar/statbar.cpp b/samples/statbar/statbar.cpp index 0887f1b027..b9ccd6f933 100644 --- a/samples/statbar/statbar.cpp +++ b/samples/statbar/statbar.cpp @@ -223,7 +223,6 @@ enum StatusBar_SetStyleShowTips }; -static const int BITMAP_SIZE_X = 32; // ---------------------------------------------------------------------------- // event tables and other macros for wxWidgets @@ -925,7 +924,7 @@ MyStatusBar::MyStatusBar(wxWindow *parent, long style) int widths[Field_Max]; widths[Field_Text] = -1; // growable widths[Field_Checkbox] = 150; - widths[Field_Bitmap] = BITMAP_SIZE_X; + widths[Field_Bitmap] = -1; // growable widths[Field_NumLockIndicator] = sizeNumLock.x; widths[Field_Clock] = 100; widths[Field_CapsLockIndicator] = dc.GetTextExtent(capslockIndicators[1]).x; @@ -936,6 +935,7 @@ MyStatusBar::MyStatusBar(wxWindow *parent, long style) #if wxUSE_CHECKBOX m_checkbox = new wxCheckBox(this, StatusBar_Checkbox, "&Toggle clock"); m_checkbox->SetValue(true); + AddFieldControl(Field_Checkbox, m_checkbox); #endif m_statbmp = new wxStaticBitmap(this, wxID_ANY, wxIcon(green_xpm)); @@ -966,24 +966,7 @@ MyStatusBar::~MyStatusBar() void MyStatusBar::OnSize(wxSizeEvent& event) { -#if wxUSE_CHECKBOX - if ( !m_checkbox ) - return; -#endif - wxRect rect; - if (!GetFieldRect(Field_Checkbox, rect)) - { - event.Skip(); - return; - } - -#if wxUSE_CHECKBOX - wxRect rectCheck = rect; - rectCheck.Deflate(2); - m_checkbox->SetSize(rectCheck); -#endif - GetFieldRect(Field_Bitmap, rect); wxSize size = m_statbmp->GetSize(); diff --git a/src/common/statbar.cpp b/src/common/statbar.cpp index 358e9fe133..04ade7fb08 100644 --- a/src/common/statbar.cpp +++ b/src/common/statbar.cpp @@ -112,6 +112,8 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow); wxStatusBarBase::wxStatusBarBase() { m_bSameWidthForAllPanes = true; + + Bind(wxEVT_SIZE, &wxStatusBarBase::OnSize, this); } wxStatusBarBase::~wxStatusBarBase() @@ -297,4 +299,40 @@ void wxStatusBarBase::PopStatusText(int number) DoUpdateStatusText(number); } +// ---------------------------------------------------------------------------- +// controls +// ---------------------------------------------------------------------------- +bool wxStatusBarBase::AddFieldControl(int n, wxWindow* win) +{ + wxCHECK_MSG( (unsigned)n < m_panes.size(), false, + "invalid status bar field index" ); + wxCHECK_MSG( !m_panes[n].GetFieldControl(), false, + "another control is already added in this field" ); + + m_panes[n].SetFieldControl(win); + + return true; +} + +void wxStatusBarBase::OnSize(wxSizeEvent& event) +{ + event.Skip(); + + if ( GetChildren().empty() ) + return; + + for ( int i = 0; i < (int)m_panes.size(); ++i ) + { + wxWindow* const win = m_panes[i].GetFieldControl(); + if ( win ) + { + wxRect rect; + if ( GetFieldRect(i, rect) ) + { + win->SetSize(rect); + } + } + } +} + #endif // wxUSE_STATUSBAR From 5ba009e861397bc0f308254327abce3a8ecf6bcd Mon Sep 17 00:00:00 2001 From: Blake-Madden Date: Sun, 26 Nov 2023 19:22:16 -0500 Subject: [PATCH 014/257] Add Catholic Feasts holiday authority class (US observances) This includes a static function to calculate Easter that can be used for other authorities. Document the wxDateTimeWorkDays and wxDateTimeHolidayAuthority classes. Closes #24094. --- include/wx/datetime.h | 91 +++++- interface/wx/datetime.h | 142 +++++++- src/common/datetime.cpp | 128 ++++++++ tests/datetime/datetimetest.cpp | 564 ++++++++++++++++++++++++++++++++ 4 files changed, 912 insertions(+), 13 deletions(-) diff --git a/include/wx/datetime.h b/include/wx/datetime.h index 1dba298b12..6e39ce424b 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -17,6 +17,8 @@ #include +#include + #include // for INT_MIN #include "wx/longlong.h" @@ -44,7 +46,7 @@ struct _SYSTEMTIME; * ? 2. getdate() function like under Solaris * + 3. text conversion for wxDateSpan * + 4. pluggable modules for the workdays calculations - * 5. wxDateTimeHolidayAuthority for Easter and other christian feasts + * 5. wxDateTimeHolidayAuthority Christian feasts outside of US */ /* @@ -1599,13 +1601,7 @@ protected: virtual bool DoIsHoliday(const wxDateTime& dt) const = 0; // this function should fill the array with all holidays between the two - // given dates - it is implemented in the base class, but in a very - // inefficient way (it just iterates over all days and uses IsHoliday() for - // each of them), so it must be overridden in the derived class where the - // base class version may be explicitly used if needed - // - // returns the number of holidays in the given range and fills holidays - // array + // given dates virtual size_t DoGetHolidaysInRange(const wxDateTime& dtStart, const wxDateTime& dtEnd, wxDateTimeArray& holidays) const = 0; @@ -1625,6 +1621,85 @@ protected: wxDateTimeArray& holidays) const override; }; +// https://marian.org/mary/feast-days +// https://www.omvusa.org/blog/catholic-holy-days-of-obligation/ +class WXDLLIMPEXP_BASE wxDateTimeUSCatholicFeasts : public wxDateTimeHolidayAuthority +{ +public: + // Easter for a given year. + // Based on https://www.geeksforgeeks.org/how-to-calculate-the-easter-date-for-a-given-year-using-gauss-algorithm/ + // Validated against 1600 to 2099, using data from: + // https://www.assa.org.au/edm (Astronomical Society of South Australia) + // https://www.census.gov/data/software/x13as/genhol/easter-dates.html (US Census Bureau) + static wxDateTime GetEaster(int year); + + // Ascension for a given year. + // Celebrated on the 40th day of Easter/ + // the sixth Thursday after Easter Sunday. + static wxDateTime GetThursdayAscension(int year) + { + const wxDateTime ascension = GetEaster(year) + wxDateSpan::Days(39); + wxASSERT_MSG( + ascension.GetWeekDay() == wxDateTime::WeekDay::Thu, + "Error in Ascension calculation!"); + return ascension; + } + + // Ascension for a given year. + // Same as traditional Ascension, but moved to the following Sunday. + static wxDateTime GetSundayAscension(int year) + { + const wxDateTime ascension = GetEaster(year) + wxDateSpan::Weeks(6); + wxASSERT_MSG( + ascension.GetWeekDay() == wxDateTime::WeekDay::Sun, + "Error in Ascension calculation!"); + return ascension; + } +protected: + bool DoIsHoliday(const wxDateTime& dt) const override + { + if (dt.IsSameDate(GetEaster(dt.GetYear())) || + dt.IsSameDate(GetThursdayAscension(dt.GetYear())) ) + { + return true; + } + for (const auto& feast : m_holyDaysOfObligation) + { + if (feast.GetMonth() == dt.GetMonth() && + feast.GetDay() == dt.GetDay()) + { + return true; + } + } + return false; + } + + size_t DoGetHolidaysInRange(const wxDateTime& dtStart, + const wxDateTime& dtEnd, + wxDateTimeArray& holidays) const override; +private: + static std::vector m_holyDaysOfObligation; +}; + +// Christmas and Easter +class WXDLLIMPEXP_BASE wxDateTimeChristianHolidays : public wxDateTimeUSCatholicFeasts +{ +protected: + bool DoIsHoliday(const wxDateTime& dt) const override + { + if (dt.IsSameDate(GetEaster(dt.GetYear())) || + (dt.GetMonth() == 12 && dt.GetDay() == 25)) + { + return true; + } + return false; + } + + size_t DoGetHolidaysInRange(const wxDateTime& dtStart, + const wxDateTime& dtEnd, + wxDateTimeArray& holidays) const override; +}; + // ============================================================================ // inline functions implementation // ============================================================================ diff --git a/interface/wx/datetime.h b/interface/wx/datetime.h index 5e6aec720c..2987a863a8 100644 --- a/interface/wx/datetime.h +++ b/interface/wx/datetime.h @@ -1679,18 +1679,111 @@ const wxDateTime wxDefaultDateTime; /** @class wxDateTimeWorkDays - @todo Write wxDateTimeWorkDays documentation. + Holiday authority that classifies all Saturdays and Sundays + as holidays. @library{wxbase} @category{data} */ -class wxDateTimeWorkDays +class wxDateTimeWorkDays : public wxDateTimeHolidayAuthority { -public: - +protected: + /** + Override which returns @true if provided date is a Saturday and Sunday. + */ + virtual bool DoIsHoliday(const wxDateTime& dt) const override; + /** + Override which returns all Saturdays and Sundays from a provided range. + */ + virtual size_t DoGetHolidaysInRange(const wxDateTime& dtStart, + const wxDateTime& dtEnd, + wxDateTimeArray& holidays) const override; }; +/** + @class wxDateTimeUSCatholicFeasts + Holiday authority that returns Catholic holy days of obligation, + as observed in the United States. This includes: + + - Solemnity of Mary, Mother of God + - Easter (moveable feast) + - Ascension (moveable feast) + - Assumption of the Blessed Virgin Mary + - All Saints Day + - Immaculate Conception of the Blessed Virgin Mary + - Christmas + + @library{wxbase} + @category{data} + + @since 3.3.0 +*/ +class wxDateTimeUSCatholicFeasts : public wxDateTimeHolidayAuthority +{ +public: + /** + Returns the date for Easter for a given year. + */ + static wxDateTime GetEaster(int year); + + /** + Returns the date for Ascension for a given year. + Celebrated on the 40th day of Easter/ + sixth Thursday after Easter Sunday. + */ + static wxDateTime GetThursdayAscension(int year); + + /** + Returns the date for Ascension for a given year. + This is the same as GetThursdayAscension(), + but moved to the Sunday following the traditional Ascension + that falls on a Thursday. + */ + static wxDateTime GetSundayAscension(int year); + +protected: + /** + Override which returns @true if provided date is a holy day of obligation. + */ + bool DoIsHoliday(const wxDateTime& dt) const override; + + /** + Override to determine the holy days of obligation within a date range. + */ + size_t DoGetHolidaysInRange(const wxDateTime& dtStart, + const wxDateTime& dtEnd, + wxDateTimeArray& holidays) const override; +}; + +/** + @class wxDateTimeChristianHolidays + + Holiday authority that returns holidays common to all Christian religions. + This includes: + + - Easter (moveable feast) + - Christmas + + @library{wxbase} + @category{data} + + @since 3.3.0 +*/ +class WXDLLIMPEXP_BASE wxDateTimeChristianHolidays : public wxDateTimeUSCatholicFeasts +{ +protected: + /** + Override which returns @true if provided date is Easter or Christmas. + */ + bool DoIsHoliday(const wxDateTime& dt) const override; + /** + Override to determine the holidays within a date range. + */ + size_t DoGetHolidaysInRange(const wxDateTime& dtStart, + const wxDateTime& dtEnd, + wxDateTimeArray& holidays) const override; +}; /** @class wxDateSpan @@ -2231,7 +2324,12 @@ public: /** @class wxDateTimeHolidayAuthority - @todo Write wxDateTimeHolidayAuthority documentation. + Class which decides whether a given + date is a holiday and is used by all functions working with "work days". + + New classes can be derived from this to determine specific holidays. + These classes should override DoIsHoliday() and DoGetHolidaysInRange(), + and be passed to wxDateTimeHolidayAuthority::AddAuthority() to be used. @library{wxbase} @category{data} @@ -2239,6 +2337,40 @@ public: class wxDateTimeHolidayAuthority { public: + /// Returns @true if the given date is a holiday. + static bool IsHoliday(const wxDateTime& dt); + /** + Fills the provided array with all holidays in the given range, returns + the number of them. + */ + static size_t GetHolidaysInRange(const wxDateTime& dtStart, + const wxDateTime& dtEnd, + wxDateTimeArray& holidays); + + /// Clears the list of holiday authorities. + static void ClearAllAuthorities(); + + /** + Adds a new holiday authority. + + The pointer will be deleted by wxDateTimeHolidayAuthority. + */ + static void AddAuthority(wxDateTimeHolidayAuthority* auth); + +protected: + /** + This function should be overridden to determine whether + a given day is a holiday. + */ + virtual bool DoIsHoliday(const wxDateTime& dt) const = 0; + + /** + This function should be overridden to fill an array with + all holidays between the two given dates. + */ + virtual size_t DoGetHolidaysInRange(const wxDateTime& dtStart, + const wxDateTime& dtEnd, + wxDateTimeArray& holidays) const = 0; }; diff --git a/src/common/datetime.cpp b/src/common/datetime.cpp index 01ee68969d..62dcf9d308 100644 --- a/src/common/datetime.cpp +++ b/src/common/datetime.cpp @@ -74,6 +74,7 @@ #include "wx/tokenzr.h" #include +#include #ifdef __WINDOWS__ #include @@ -2271,6 +2272,133 @@ size_t wxDateTimeWorkDays::DoGetHolidaysInRange(const wxDateTime& dtStart, return holidays.GetCount(); } +// ---------------------------------------------------------------------------- +// wxDateTimeUSCatholicFeasts +// ---------------------------------------------------------------------------- + +std::vector wxDateTimeUSCatholicFeasts::m_holyDaysOfObligation = +{ + // Feasts with fixed dates + { wxDateTime(1, wxDateTime::Month::Jan, 0) }, // Solemnity of Mary, Mother of God + { wxDateTime(15, wxDateTime::Month::Aug, 0) }, // Assumption of the Blessed Virgin Mary + { wxDateTime(1, wxDateTime::Month::Nov, 0) }, // All Saints Day + { wxDateTime(8, wxDateTime::Month::Dec, 0) }, // Immaculate Conception of the Blessed Virgin Mary + { wxDateTime(25, wxDateTime::Month::Dec, 0) } // Christmas +}; + +wxDateTime wxDateTimeUSCatholicFeasts::GetEaster(int year) +{ + // Adjust for miscalculation in Gauss formula + if (year == 1734 || year == 1886) + { + return wxDateTime(25, wxDateTime::Apr, year); + } + + // All calculations done + // on the basis of + // Gauss Easter Algorithm + const float A = year % 19; + const float B = year % 4; + const float C = year % 7; + const float P = std::floor((float)year / 100.0); + + const float Q = std::floor((float)(13 + 8 * P) / 25.0); + + const float M = (int)(15 - Q + P - std::floor((float)P / 4)) % 30; + + const float N = (int)(4 + P - std::floor((float)P / 4)) % 7; + + const float D = (int)(19 * A + M) % 30; + + const float E = (int)(2 * B + 4 * C + 6 * D + N) % 7; + + const int days = (int)(22 + D + E); + + // A corner case, + // when D is 29 + if ((D == 29) && (E == 6)) + { + wxASSERT_MSG( + wxDateTime(19, wxDateTime::Apr, year).GetWeekDay() == + wxDateTime::WeekDay::Sun, + "Error in Easter calculation!"); + return wxDateTime(19, wxDateTime::Apr, year); + } + // Another corner case, + // when D is 28 + else if ((D == 28) && (E == 6)) + { + wxASSERT_MSG( + wxDateTime(18, wxDateTime::Apr, year).GetWeekDay() == + wxDateTime::WeekDay::Sun, + "Error in Easter calculation!"); + return wxDateTime(18, wxDateTime::Apr, year); + } + else + { + // If days > 31, move to April + // April = 4th Month + if (days > 31) + { + wxASSERT_MSG( + wxDateTime((days - 31), wxDateTime::Apr, year).GetWeekDay() == + wxDateTime::WeekDay::Sun, + "Error in Easter calculation!"); + return wxDateTime((days - 31), wxDateTime::Apr, year); + } + else + { + // Otherwise, stay on March + // March = 3rd Month + wxASSERT_MSG( + wxDateTime(days, wxDateTime::Mar, year).GetWeekDay() == + wxDateTime::WeekDay::Sun, + "Error in Easter calculation!"); + return wxDateTime(days, wxDateTime::Mar, year); + } + } +} + +size_t wxDateTimeUSCatholicFeasts::DoGetHolidaysInRange(const wxDateTime& dtStart, + const wxDateTime& dtEnd, + wxDateTimeArray& holidays) const +{ + holidays.Clear(); + + for (wxDateTime dt = dtStart; dt <= dtEnd; dt += wxDateSpan::Day()) + { + if (DoIsHoliday(dt) ) + { + holidays.Add(dt); + continue; + } + } + + return holidays.size(); +} + +// ---------------------------------------------------------------------------- +// wxDateTimeChristianHolidays +// ---------------------------------------------------------------------------- + +size_t wxDateTimeChristianHolidays::DoGetHolidaysInRange(const wxDateTime& dtStart, + const wxDateTime& dtEnd, + wxDateTimeArray& holidays) const +{ + holidays.Clear(); + + for (wxDateTime dt = dtStart; dt <= dtEnd; dt += wxDateSpan::Day()) + { + if (DoIsHoliday(dt) ) + { + holidays.Add(dt); + continue; + } + } + + return holidays.size(); +} + // ============================================================================ // other helper functions // ============================================================================ diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp index 3d4c735342..43c3d94cf3 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -2025,4 +2025,568 @@ TEST_CASE("wxDateTime::UNow", "[datetime][now][unow]") CHECK( gotMS ); } +TEST_CASE("Easter", "[datetime][holiday][easter]") +{ + std::vector easters = + { + wxDateTime( 2, wxDateTime::Apr, 1600), + wxDateTime(22, wxDateTime::Apr, 1601), + wxDateTime( 7, wxDateTime::Apr, 1602), + wxDateTime(30, wxDateTime::Mar, 1603), + wxDateTime(18, wxDateTime::Apr, 1604), + wxDateTime(10, wxDateTime::Apr, 1605), + wxDateTime(26, wxDateTime::Mar, 1606), + wxDateTime(15, wxDateTime::Apr, 1607), + wxDateTime( 6, wxDateTime::Apr, 1608), + wxDateTime(19, wxDateTime::Apr, 1609), + wxDateTime(11, wxDateTime::Apr, 1610), + wxDateTime( 3, wxDateTime::Apr, 1611), + wxDateTime(22, wxDateTime::Apr, 1612), + wxDateTime( 7, wxDateTime::Apr, 1613), + wxDateTime(30, wxDateTime::Mar, 1614), + wxDateTime(19, wxDateTime::Apr, 1615), + wxDateTime( 3, wxDateTime::Apr, 1616), + wxDateTime(26, wxDateTime::Mar, 1617), + wxDateTime(15, wxDateTime::Apr, 1618), + wxDateTime(31, wxDateTime::Mar, 1619), + wxDateTime(19, wxDateTime::Apr, 1620), + wxDateTime(11, wxDateTime::Apr, 1621), + wxDateTime(27, wxDateTime::Mar, 1622), + wxDateTime(16, wxDateTime::Apr, 1623), + wxDateTime( 7, wxDateTime::Apr, 1624), + wxDateTime(30, wxDateTime::Mar, 1625), + wxDateTime(12, wxDateTime::Apr, 1626), + wxDateTime( 4, wxDateTime::Apr, 1627), + wxDateTime(23, wxDateTime::Apr, 1628), + wxDateTime(15, wxDateTime::Apr, 1629), + wxDateTime(31, wxDateTime::Mar, 1630), + wxDateTime(20, wxDateTime::Apr, 1631), + wxDateTime(11, wxDateTime::Apr, 1632), + wxDateTime(27, wxDateTime::Mar, 1633), + wxDateTime(16, wxDateTime::Apr, 1634), + wxDateTime( 8, wxDateTime::Apr, 1635), + wxDateTime(23, wxDateTime::Mar, 1636), + wxDateTime(12, wxDateTime::Apr, 1637), + wxDateTime( 4, wxDateTime::Apr, 1638), + wxDateTime(24, wxDateTime::Apr, 1639), + wxDateTime( 8, wxDateTime::Apr, 1640), + wxDateTime(31, wxDateTime::Mar, 1641), + wxDateTime(20, wxDateTime::Apr, 1642), + wxDateTime( 5, wxDateTime::Apr, 1643), + wxDateTime(27, wxDateTime::Mar, 1644), + wxDateTime(16, wxDateTime::Apr, 1645), + wxDateTime( 1, wxDateTime::Apr, 1646), + wxDateTime(21, wxDateTime::Apr, 1647), + wxDateTime(12, wxDateTime::Apr, 1648), + wxDateTime( 4, wxDateTime::Apr, 1649), + wxDateTime(17, wxDateTime::Apr, 1650), + wxDateTime( 9, wxDateTime::Apr, 1651), + wxDateTime(31, wxDateTime::Mar, 1652), + wxDateTime(13, wxDateTime::Apr, 1653), + wxDateTime( 5, wxDateTime::Apr, 1654), + wxDateTime(28, wxDateTime::Mar, 1655), + wxDateTime(16, wxDateTime::Apr, 1656), + wxDateTime( 1, wxDateTime::Apr, 1657), + wxDateTime(21, wxDateTime::Apr, 1658), + wxDateTime(13, wxDateTime::Apr, 1659), + wxDateTime(28, wxDateTime::Mar, 1660), + wxDateTime(17, wxDateTime::Apr, 1661), + wxDateTime( 9, wxDateTime::Apr, 1662), + wxDateTime(25, wxDateTime::Mar, 1663), + wxDateTime(13, wxDateTime::Apr, 1664), + wxDateTime( 5, wxDateTime::Apr, 1665), + wxDateTime(25, wxDateTime::Apr, 1666), + wxDateTime(10, wxDateTime::Apr, 1667), + wxDateTime( 1, wxDateTime::Apr, 1668), + wxDateTime(21, wxDateTime::Apr, 1669), + wxDateTime( 6, wxDateTime::Apr, 1670), + wxDateTime(29, wxDateTime::Mar, 1671), + wxDateTime(17, wxDateTime::Apr, 1672), + wxDateTime( 2, wxDateTime::Apr, 1673), + wxDateTime(25, wxDateTime::Mar, 1674), + wxDateTime(14, wxDateTime::Apr, 1675), + wxDateTime( 5, wxDateTime::Apr, 1676), + wxDateTime(18, wxDateTime::Apr, 1677), + wxDateTime(10, wxDateTime::Apr, 1678), + wxDateTime( 2, wxDateTime::Apr, 1679), + wxDateTime(21, wxDateTime::Apr, 1680), + wxDateTime( 6, wxDateTime::Apr, 1681), + wxDateTime(29, wxDateTime::Mar, 1682), + wxDateTime(18, wxDateTime::Apr, 1683), + wxDateTime( 2, wxDateTime::Apr, 1684), + wxDateTime(22, wxDateTime::Apr, 1685), + wxDateTime(14, wxDateTime::Apr, 1686), + wxDateTime(30, wxDateTime::Mar, 1687), + wxDateTime(18, wxDateTime::Apr, 1688), + wxDateTime(10, wxDateTime::Apr, 1689), + wxDateTime(26, wxDateTime::Mar, 1690), + wxDateTime(15, wxDateTime::Apr, 1691), + wxDateTime( 6, wxDateTime::Apr, 1692), + wxDateTime(22, wxDateTime::Mar, 1693), + wxDateTime(11, wxDateTime::Apr, 1694), + wxDateTime( 3, wxDateTime::Apr, 1695), + wxDateTime(22, wxDateTime::Apr, 1696), + wxDateTime( 7, wxDateTime::Apr, 1697), + wxDateTime(30, wxDateTime::Mar, 1698), + wxDateTime(19, wxDateTime::Apr, 1699), + wxDateTime(11, wxDateTime::Apr, 1700), + wxDateTime(27, wxDateTime::Mar, 1701), + wxDateTime(16, wxDateTime::Apr, 1702), + wxDateTime( 8, wxDateTime::Apr, 1703), + wxDateTime(23, wxDateTime::Mar, 1704), + wxDateTime(12, wxDateTime::Apr, 1705), + wxDateTime( 4, wxDateTime::Apr, 1706), + wxDateTime(24, wxDateTime::Apr, 1707), + wxDateTime( 8, wxDateTime::Apr, 1708), + wxDateTime(31, wxDateTime::Mar, 1709), + wxDateTime(20, wxDateTime::Apr, 1710), + wxDateTime( 5, wxDateTime::Apr, 1711), + wxDateTime(27, wxDateTime::Mar, 1712), + wxDateTime(16, wxDateTime::Apr, 1713), + wxDateTime( 1, wxDateTime::Apr, 1714), + wxDateTime(21, wxDateTime::Apr, 1715), + wxDateTime(12, wxDateTime::Apr, 1716), + wxDateTime(28, wxDateTime::Mar, 1717), + wxDateTime(17, wxDateTime::Apr, 1718), + wxDateTime( 9, wxDateTime::Apr, 1719), + wxDateTime(31, wxDateTime::Mar, 1720), + wxDateTime(13, wxDateTime::Apr, 1721), + wxDateTime( 5, wxDateTime::Apr, 1722), + wxDateTime(28, wxDateTime::Mar, 1723), + wxDateTime(16, wxDateTime::Apr, 1724), + wxDateTime( 1, wxDateTime::Apr, 1725), + wxDateTime(21, wxDateTime::Apr, 1726), + wxDateTime(13, wxDateTime::Apr, 1727), + wxDateTime(28, wxDateTime::Mar, 1728), + wxDateTime(17, wxDateTime::Apr, 1729), + wxDateTime( 9, wxDateTime::Apr, 1730), + wxDateTime(25, wxDateTime::Mar, 1731), + wxDateTime(13, wxDateTime::Apr, 1732), + wxDateTime( 5, wxDateTime::Apr, 1733), + wxDateTime(25, wxDateTime::Apr, 1734), + wxDateTime(10, wxDateTime::Apr, 1735), + wxDateTime( 1, wxDateTime::Apr, 1736), + wxDateTime(21, wxDateTime::Apr, 1737), + wxDateTime( 6, wxDateTime::Apr, 1738), + wxDateTime(29, wxDateTime::Mar, 1739), + wxDateTime(17, wxDateTime::Apr, 1740), + wxDateTime( 2, wxDateTime::Apr, 1741), + wxDateTime(25, wxDateTime::Mar, 1742), + wxDateTime(14, wxDateTime::Apr, 1743), + wxDateTime( 5, wxDateTime::Apr, 1744), + wxDateTime(18, wxDateTime::Apr, 1745), + wxDateTime(10, wxDateTime::Apr, 1746), + wxDateTime( 2, wxDateTime::Apr, 1747), + wxDateTime(14, wxDateTime::Apr, 1748), + wxDateTime( 6, wxDateTime::Apr, 1749), + wxDateTime(29, wxDateTime::Mar, 1750), + wxDateTime(11, wxDateTime::Apr, 1751), + wxDateTime( 2, wxDateTime::Apr, 1752), + wxDateTime(22, wxDateTime::Apr, 1753), + wxDateTime(14, wxDateTime::Apr, 1754), + wxDateTime(30, wxDateTime::Mar, 1755), + wxDateTime(18, wxDateTime::Apr, 1756), + wxDateTime(10, wxDateTime::Apr, 1757), + wxDateTime(26, wxDateTime::Mar, 1758), + wxDateTime(15, wxDateTime::Apr, 1759), + wxDateTime( 6, wxDateTime::Apr, 1760), + wxDateTime(22, wxDateTime::Mar, 1761), + wxDateTime(11, wxDateTime::Apr, 1762), + wxDateTime( 3, wxDateTime::Apr, 1763), + wxDateTime(22, wxDateTime::Apr, 1764), + wxDateTime( 7, wxDateTime::Apr, 1765), + wxDateTime(30, wxDateTime::Mar, 1766), + wxDateTime(19, wxDateTime::Apr, 1767), + wxDateTime( 3, wxDateTime::Apr, 1768), + wxDateTime(26, wxDateTime::Mar, 1769), + wxDateTime(15, wxDateTime::Apr, 1770), + wxDateTime(31, wxDateTime::Mar, 1771), + wxDateTime(19, wxDateTime::Apr, 1772), + wxDateTime(11, wxDateTime::Apr, 1773), + wxDateTime( 3, wxDateTime::Apr, 1774), + wxDateTime(16, wxDateTime::Apr, 1775), + wxDateTime( 7, wxDateTime::Apr, 1776), + wxDateTime(30, wxDateTime::Mar, 1777), + wxDateTime(19, wxDateTime::Apr, 1778), + wxDateTime( 4, wxDateTime::Apr, 1779), + wxDateTime(26, wxDateTime::Mar, 1780), + wxDateTime(15, wxDateTime::Apr, 1781), + wxDateTime(31, wxDateTime::Mar, 1782), + wxDateTime(20, wxDateTime::Apr, 1783), + wxDateTime(11, wxDateTime::Apr, 1784), + wxDateTime(27, wxDateTime::Mar, 1785), + wxDateTime(16, wxDateTime::Apr, 1786), + wxDateTime( 8, wxDateTime::Apr, 1787), + wxDateTime(23, wxDateTime::Mar, 1788), + wxDateTime(12, wxDateTime::Apr, 1789), + wxDateTime( 4, wxDateTime::Apr, 1790), + wxDateTime(24, wxDateTime::Apr, 1791), + wxDateTime( 8, wxDateTime::Apr, 1792), + wxDateTime(31, wxDateTime::Mar, 1793), + wxDateTime(20, wxDateTime::Apr, 1794), + wxDateTime( 5, wxDateTime::Apr, 1795), + wxDateTime(27, wxDateTime::Mar, 1796), + wxDateTime(16, wxDateTime::Apr, 1797), + wxDateTime( 8, wxDateTime::Apr, 1798), + wxDateTime(24, wxDateTime::Mar, 1799), + wxDateTime(13, wxDateTime::Apr, 1800), + wxDateTime( 5, wxDateTime::Apr, 1801), + wxDateTime(18, wxDateTime::Apr, 1802), + wxDateTime(10, wxDateTime::Apr, 1803), + wxDateTime( 1, wxDateTime::Apr, 1804), + wxDateTime(14, wxDateTime::Apr, 1805), + wxDateTime( 6, wxDateTime::Apr, 1806), + wxDateTime(29, wxDateTime::Mar, 1807), + wxDateTime(17, wxDateTime::Apr, 1808), + wxDateTime( 2, wxDateTime::Apr, 1809), + wxDateTime(22, wxDateTime::Apr, 1810), + wxDateTime(14, wxDateTime::Apr, 1811), + wxDateTime(29, wxDateTime::Mar, 1812), + wxDateTime(18, wxDateTime::Apr, 1813), + wxDateTime(10, wxDateTime::Apr, 1814), + wxDateTime(26, wxDateTime::Mar, 1815), + wxDateTime(14, wxDateTime::Apr, 1816), + wxDateTime( 6, wxDateTime::Apr, 1817), + wxDateTime(22, wxDateTime::Mar, 1818), + wxDateTime(11, wxDateTime::Apr, 1819), + wxDateTime( 2, wxDateTime::Apr, 1820), + wxDateTime(22, wxDateTime::Apr, 1821), + wxDateTime( 7, wxDateTime::Apr, 1822), + wxDateTime(30, wxDateTime::Mar, 1823), + wxDateTime(18, wxDateTime::Apr, 1824), + wxDateTime( 3, wxDateTime::Apr, 1825), + wxDateTime(26, wxDateTime::Mar, 1826), + wxDateTime(15, wxDateTime::Apr, 1827), + wxDateTime( 6, wxDateTime::Apr, 1828), + wxDateTime(19, wxDateTime::Apr, 1829), + wxDateTime(11, wxDateTime::Apr, 1830), + wxDateTime( 3, wxDateTime::Apr, 1831), + wxDateTime(22, wxDateTime::Apr, 1832), + wxDateTime( 7, wxDateTime::Apr, 1833), + wxDateTime(30, wxDateTime::Mar, 1834), + wxDateTime(19, wxDateTime::Apr, 1835), + wxDateTime( 3, wxDateTime::Apr, 1836), + wxDateTime(26, wxDateTime::Mar, 1837), + wxDateTime(15, wxDateTime::Apr, 1838), + wxDateTime(31, wxDateTime::Mar, 1839), + wxDateTime(19, wxDateTime::Apr, 1840), + wxDateTime(11, wxDateTime::Apr, 1841), + wxDateTime(27, wxDateTime::Mar, 1842), + wxDateTime(16, wxDateTime::Apr, 1843), + wxDateTime( 7, wxDateTime::Apr, 1844), + wxDateTime(23, wxDateTime::Mar, 1845), + wxDateTime(12, wxDateTime::Apr, 1846), + wxDateTime( 4, wxDateTime::Apr, 1847), + wxDateTime(23, wxDateTime::Apr, 1848), + wxDateTime( 8, wxDateTime::Apr, 1849), + wxDateTime(31, wxDateTime::Mar, 1850), + wxDateTime(20, wxDateTime::Apr, 1851), + wxDateTime(11, wxDateTime::Apr, 1852), + wxDateTime(27, wxDateTime::Mar, 1853), + wxDateTime(16, wxDateTime::Apr, 1854), + wxDateTime( 8, wxDateTime::Apr, 1855), + wxDateTime(23, wxDateTime::Mar, 1856), + wxDateTime(12, wxDateTime::Apr, 1857), + wxDateTime( 4, wxDateTime::Apr, 1858), + wxDateTime(24, wxDateTime::Apr, 1859), + wxDateTime( 8, wxDateTime::Apr, 1860), + wxDateTime(31, wxDateTime::Mar, 1861), + wxDateTime(20, wxDateTime::Apr, 1862), + wxDateTime( 5, wxDateTime::Apr, 1863), + wxDateTime(27, wxDateTime::Mar, 1864), + wxDateTime(16, wxDateTime::Apr, 1865), + wxDateTime( 1, wxDateTime::Apr, 1866), + wxDateTime(21, wxDateTime::Apr, 1867), + wxDateTime(12, wxDateTime::Apr, 1868), + wxDateTime(28, wxDateTime::Mar, 1869), + wxDateTime(17, wxDateTime::Apr, 1870), + wxDateTime( 9, wxDateTime::Apr, 1871), + wxDateTime(31, wxDateTime::Mar, 1872), + wxDateTime(13, wxDateTime::Apr, 1873), + wxDateTime( 5, wxDateTime::Apr, 1874), + wxDateTime(28, wxDateTime::Mar, 1875), + wxDateTime(16, wxDateTime::Apr, 1876), + wxDateTime( 1, wxDateTime::Apr, 1877), + wxDateTime(21, wxDateTime::Apr, 1878), + wxDateTime(13, wxDateTime::Apr, 1879), + wxDateTime(28, wxDateTime::Mar, 1880), + wxDateTime(17, wxDateTime::Apr, 1881), + wxDateTime( 9, wxDateTime::Apr, 1882), + wxDateTime(25, wxDateTime::Mar, 1883), + wxDateTime(13, wxDateTime::Apr, 1884), + wxDateTime( 5, wxDateTime::Apr, 1885), + wxDateTime(25, wxDateTime::Apr, 1886), + wxDateTime(10, wxDateTime::Apr, 1887), + wxDateTime( 1, wxDateTime::Apr, 1888), + wxDateTime(21, wxDateTime::Apr, 1889), + wxDateTime( 6, wxDateTime::Apr, 1890), + wxDateTime(29, wxDateTime::Mar, 1891), + wxDateTime(17, wxDateTime::Apr, 1892), + wxDateTime( 2, wxDateTime::Apr, 1893), + wxDateTime(25, wxDateTime::Mar, 1894), + wxDateTime(14, wxDateTime::Apr, 1895), + wxDateTime( 5, wxDateTime::Apr, 1896), + wxDateTime(18, wxDateTime::Apr, 1897), + wxDateTime(10, wxDateTime::Apr, 1898), + wxDateTime( 2, wxDateTime::Apr, 1899), + wxDateTime(15, wxDateTime::Apr, 1900), + wxDateTime( 7, wxDateTime::Apr, 1901), + wxDateTime(30, wxDateTime::Mar, 1902), + wxDateTime(12, wxDateTime::Apr, 1903), + wxDateTime( 3, wxDateTime::Apr, 1904), + wxDateTime(23, wxDateTime::Apr, 1905), + wxDateTime(15, wxDateTime::Apr, 1906), + wxDateTime(31, wxDateTime::Mar, 1907), + wxDateTime(19, wxDateTime::Apr, 1908), + wxDateTime(11, wxDateTime::Apr, 1909), + wxDateTime(27, wxDateTime::Mar, 1910), + wxDateTime(16, wxDateTime::Apr, 1911), + wxDateTime( 7, wxDateTime::Apr, 1912), + wxDateTime(23, wxDateTime::Mar, 1913), + wxDateTime(12, wxDateTime::Apr, 1914), + wxDateTime( 4, wxDateTime::Apr, 1915), + wxDateTime(23, wxDateTime::Apr, 1916), + wxDateTime( 8, wxDateTime::Apr, 1917), + wxDateTime(31, wxDateTime::Mar, 1918), + wxDateTime(20, wxDateTime::Apr, 1919), + wxDateTime( 4, wxDateTime::Apr, 1920), + wxDateTime(27, wxDateTime::Mar, 1921), + wxDateTime(16, wxDateTime::Apr, 1922), + wxDateTime( 1, wxDateTime::Apr, 1923), + wxDateTime(20, wxDateTime::Apr, 1924), + wxDateTime(12, wxDateTime::Apr, 1925), + wxDateTime( 4, wxDateTime::Apr, 1926), + wxDateTime(17, wxDateTime::Apr, 1927), + wxDateTime( 8, wxDateTime::Apr, 1928), + wxDateTime(31, wxDateTime::Mar, 1929), + wxDateTime(20, wxDateTime::Apr, 1930), + wxDateTime( 5, wxDateTime::Apr, 1931), + wxDateTime(27, wxDateTime::Mar, 1932), + wxDateTime(16, wxDateTime::Apr, 1933), + wxDateTime( 1, wxDateTime::Apr, 1934), + wxDateTime(21, wxDateTime::Apr, 1935), + wxDateTime(12, wxDateTime::Apr, 1936), + wxDateTime(28, wxDateTime::Mar, 1937), + wxDateTime(17, wxDateTime::Apr, 1938), + wxDateTime( 9, wxDateTime::Apr, 1939), + wxDateTime(24, wxDateTime::Mar, 1940), + wxDateTime(13, wxDateTime::Apr, 1941), + wxDateTime( 5, wxDateTime::Apr, 1942), + wxDateTime(25, wxDateTime::Apr, 1943), + wxDateTime( 9, wxDateTime::Apr, 1944), + wxDateTime( 1, wxDateTime::Apr, 1945), + wxDateTime(21, wxDateTime::Apr, 1946), + wxDateTime( 6, wxDateTime::Apr, 1947), + wxDateTime(28, wxDateTime::Mar, 1948), + wxDateTime(17, wxDateTime::Apr, 1949), + wxDateTime( 9, wxDateTime::Apr, 1950), + wxDateTime(25, wxDateTime::Mar, 1951), + wxDateTime(13, wxDateTime::Apr, 1952), + wxDateTime( 5, wxDateTime::Apr, 1953), + wxDateTime(18, wxDateTime::Apr, 1954), + wxDateTime(10, wxDateTime::Apr, 1955), + wxDateTime( 1, wxDateTime::Apr, 1956), + wxDateTime(21, wxDateTime::Apr, 1957), + wxDateTime( 6, wxDateTime::Apr, 1958), + wxDateTime(29, wxDateTime::Mar, 1959), + wxDateTime(17, wxDateTime::Apr, 1960), + wxDateTime( 2, wxDateTime::Apr, 1961), + wxDateTime(22, wxDateTime::Apr, 1962), + wxDateTime(14, wxDateTime::Apr, 1963), + wxDateTime(29, wxDateTime::Mar, 1964), + wxDateTime(18, wxDateTime::Apr, 1965), + wxDateTime(10, wxDateTime::Apr, 1966), + wxDateTime(26, wxDateTime::Mar, 1967), + wxDateTime(14, wxDateTime::Apr, 1968), + wxDateTime( 6, wxDateTime::Apr, 1969), + wxDateTime(29, wxDateTime::Mar, 1970), + wxDateTime(11, wxDateTime::Apr, 1971), + wxDateTime( 2, wxDateTime::Apr, 1972), + wxDateTime(22, wxDateTime::Apr, 1973), + wxDateTime(14, wxDateTime::Apr, 1974), + wxDateTime(30, wxDateTime::Mar, 1975), + wxDateTime(18, wxDateTime::Apr, 1976), + wxDateTime(10, wxDateTime::Apr, 1977), + wxDateTime(26, wxDateTime::Mar, 1978), + wxDateTime(15, wxDateTime::Apr, 1979), + wxDateTime( 6, wxDateTime::Apr, 1980), + wxDateTime(19, wxDateTime::Apr, 1981), + wxDateTime(11, wxDateTime::Apr, 1982), + wxDateTime( 3, wxDateTime::Apr, 1983), + wxDateTime(22, wxDateTime::Apr, 1984), + wxDateTime( 7, wxDateTime::Apr, 1985), + wxDateTime(30, wxDateTime::Mar, 1986), + wxDateTime(19, wxDateTime::Apr, 1987), + wxDateTime( 3, wxDateTime::Apr, 1988), + wxDateTime(26, wxDateTime::Mar, 1989), + wxDateTime(15, wxDateTime::Apr, 1990), + wxDateTime(31, wxDateTime::Mar, 1991), + wxDateTime(19, wxDateTime::Apr, 1992), + wxDateTime(11, wxDateTime::Apr, 1993), + wxDateTime( 3, wxDateTime::Apr, 1994), + wxDateTime(16, wxDateTime::Apr, 1995), + wxDateTime( 7, wxDateTime::Apr, 1996), + wxDateTime(30, wxDateTime::Mar, 1997), + wxDateTime(12, wxDateTime::Apr, 1998), + wxDateTime( 4, wxDateTime::Apr, 1999), + wxDateTime(23, wxDateTime::Apr, 2000), + wxDateTime(15, wxDateTime::Apr, 2001), + wxDateTime(31, wxDateTime::Mar, 2002), + wxDateTime(20, wxDateTime::Apr, 2003), + wxDateTime(11, wxDateTime::Apr, 2004), + wxDateTime(27, wxDateTime::Mar, 2005), + wxDateTime(16, wxDateTime::Apr, 2006), + wxDateTime( 8, wxDateTime::Apr, 2007), + wxDateTime(23, wxDateTime::Mar, 2008), + wxDateTime(12, wxDateTime::Apr, 2009), + wxDateTime( 4, wxDateTime::Apr, 2010), + wxDateTime(24, wxDateTime::Apr, 2011), + wxDateTime( 8, wxDateTime::Apr, 2012), + wxDateTime(31, wxDateTime::Mar, 2013), + wxDateTime(20, wxDateTime::Apr, 2014), + wxDateTime( 5, wxDateTime::Apr, 2015), + wxDateTime(27, wxDateTime::Mar, 2016), + wxDateTime(16, wxDateTime::Apr, 2017), + wxDateTime( 1, wxDateTime::Apr, 2018), + wxDateTime(21, wxDateTime::Apr, 2019), + wxDateTime(12, wxDateTime::Apr, 2020), + wxDateTime( 4, wxDateTime::Apr, 2021), + wxDateTime(17, wxDateTime::Apr, 2022), + wxDateTime( 9, wxDateTime::Apr, 2023), + wxDateTime(31, wxDateTime::Mar, 2024), + wxDateTime(20, wxDateTime::Apr, 2025), + wxDateTime( 5, wxDateTime::Apr, 2026), + wxDateTime(28, wxDateTime::Mar, 2027), + wxDateTime(16, wxDateTime::Apr, 2028), + wxDateTime( 1, wxDateTime::Apr, 2029), + wxDateTime(21, wxDateTime::Apr, 2030), + wxDateTime(13, wxDateTime::Apr, 2031), + wxDateTime(28, wxDateTime::Mar, 2032), + wxDateTime(17, wxDateTime::Apr, 2033), + wxDateTime( 9, wxDateTime::Apr, 2034), + wxDateTime(25, wxDateTime::Mar, 2035), + wxDateTime(13, wxDateTime::Apr, 2036), + wxDateTime( 5, wxDateTime::Apr, 2037), + wxDateTime(25, wxDateTime::Apr, 2038), + wxDateTime(10, wxDateTime::Apr, 2039), + wxDateTime( 1, wxDateTime::Apr, 2040), + wxDateTime(21, wxDateTime::Apr, 2041), + wxDateTime( 6, wxDateTime::Apr, 2042), + wxDateTime(29, wxDateTime::Mar, 2043), + wxDateTime(17, wxDateTime::Apr, 2044), + wxDateTime( 9, wxDateTime::Apr, 2045), + wxDateTime(25, wxDateTime::Mar, 2046), + wxDateTime(14, wxDateTime::Apr, 2047), + wxDateTime( 5, wxDateTime::Apr, 2048), + wxDateTime(18, wxDateTime::Apr, 2049), + wxDateTime(10, wxDateTime::Apr, 2050), + wxDateTime( 2, wxDateTime::Apr, 2051), + wxDateTime(21, wxDateTime::Apr, 2052), + wxDateTime( 6, wxDateTime::Apr, 2053), + wxDateTime(29, wxDateTime::Mar, 2054), + wxDateTime(18, wxDateTime::Apr, 2055), + wxDateTime( 2, wxDateTime::Apr, 2056), + wxDateTime(22, wxDateTime::Apr, 2057), + wxDateTime(14, wxDateTime::Apr, 2058), + wxDateTime(30, wxDateTime::Mar, 2059), + wxDateTime(18, wxDateTime::Apr, 2060), + wxDateTime(10, wxDateTime::Apr, 2061), + wxDateTime(26, wxDateTime::Mar, 2062), + wxDateTime(15, wxDateTime::Apr, 2063), + wxDateTime( 6, wxDateTime::Apr, 2064), + wxDateTime(29, wxDateTime::Mar, 2065), + wxDateTime(11, wxDateTime::Apr, 2066), + wxDateTime( 3, wxDateTime::Apr, 2067), + wxDateTime(22, wxDateTime::Apr, 2068), + wxDateTime(14, wxDateTime::Apr, 2069), + wxDateTime(30, wxDateTime::Mar, 2070), + wxDateTime(19, wxDateTime::Apr, 2071), + wxDateTime(10, wxDateTime::Apr, 2072), + wxDateTime(26, wxDateTime::Mar, 2073), + wxDateTime(15, wxDateTime::Apr, 2074), + wxDateTime( 7, wxDateTime::Apr, 2075), + wxDateTime(19, wxDateTime::Apr, 2076), + wxDateTime(11, wxDateTime::Apr, 2077), + wxDateTime( 3, wxDateTime::Apr, 2078), + wxDateTime(23, wxDateTime::Apr, 2079), + wxDateTime( 7, wxDateTime::Apr, 2080), + wxDateTime(30, wxDateTime::Mar, 2081), + wxDateTime(19, wxDateTime::Apr, 2082), + wxDateTime( 4, wxDateTime::Apr, 2083), + wxDateTime(26, wxDateTime::Mar, 2084), + wxDateTime(15, wxDateTime::Apr, 2085), + wxDateTime(31, wxDateTime::Mar, 2086), + wxDateTime(20, wxDateTime::Apr, 2087), + wxDateTime(11, wxDateTime::Apr, 2088), + wxDateTime( 3, wxDateTime::Apr, 2089), + wxDateTime(16, wxDateTime::Apr, 2090), + wxDateTime( 8, wxDateTime::Apr, 2091), + wxDateTime(30, wxDateTime::Mar, 2092), + wxDateTime(12, wxDateTime::Apr, 2093), + wxDateTime( 4, wxDateTime::Apr, 2094), + wxDateTime(24, wxDateTime::Apr, 2095), + wxDateTime(15, wxDateTime::Apr, 2096), + wxDateTime(31, wxDateTime::Mar, 2097), + wxDateTime(20, wxDateTime::Apr, 2098), + wxDateTime(12, wxDateTime::Apr, 2099) + }; + + for (const auto& easter : easters) + { + INFO("Checking year " << easter.GetYear()); + CHECK(wxDateTimeUSCatholicFeasts::GetEaster(easter.GetYear()).IsSameDate(easter)); + } +} + +TEST_CASE("US Catholic Holidays", "[datetime][holiday]") +{ + SECTION("Ascension") + { + wxDateTime ascension = wxDateTimeUSCatholicFeasts::GetThursdayAscension(2023); + CHECK(ascension.GetMonth() == wxDateTime::Month::May); + CHECK(ascension.GetDay() == 18); + + ascension = wxDateTimeUSCatholicFeasts::GetSundayAscension(2023); + CHECK(ascension.GetMonth() == wxDateTime::Month::May); + CHECK(ascension.GetDay() == 21); + } + SECTION("Fixed date feasts") + { + wxDateTimeHolidayAuthority::AddAuthority(new wxDateTimeUSCatholicFeasts); + CHECK(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime( 1, wxDateTime::Month::Jan, 2024))); + CHECK(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime(15, wxDateTime::Month::Aug, 2023))); + CHECK(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime( 1, wxDateTime::Month::Nov, 2023))); + CHECK(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime( 8, wxDateTime::Month::Dec, 2023))); + CHECK(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime(25, wxDateTime::Month::Dec, 2023))); + // random days that should not be feasts of obligation + CHECK_FALSE(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime( 1, wxDateTime::Month::Dec, 2023))); + CHECK_FALSE(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime(31, wxDateTime::Month::Oct, 2023))); + CHECK_FALSE(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime(14, wxDateTime::Month::Feb, 2023))); + } +} + +TEST_CASE("Christian Holidays", "[datetime][holiday][christian]") +{ + SECTION("Easter") + { + wxDateTime easter = wxDateTimeChristianHolidays::GetEaster(2023); + CHECK(easter.GetMonth() == wxDateTime::Month::Apr); + CHECK(easter.GetDay() == 9); + + easter = wxDateTimeChristianHolidays::GetEaster(2010); + CHECK(easter.GetMonth() == wxDateTime::Month::Apr); + CHECK(easter.GetDay() == 4); + } + SECTION("Christmas") + { + wxDateTimeHolidayAuthority::AddAuthority(new wxDateTimeChristianHolidays); + CHECK(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime(25, wxDateTime::Month::Dec, 1990))); + CHECK(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime(25, wxDateTime::Month::Dec, 1700))); + CHECK(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime(25, wxDateTime::Month::Dec, 2023))); + // random days that are not Christmas or weekends + CHECK_FALSE(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime(1, wxDateTime::Month::Dec, 2023))); + CHECK_FALSE(wxDateTimeHolidayAuthority::IsHoliday(wxDateTime(29, wxDateTime::Month::Dec, 2023))); + } +} + #endif // wxUSE_DATETIME From 0965698c585df8b4bf744d8eac7056197b1fa2be Mon Sep 17 00:00:00 2001 From: Miguel Gimenez Date: Sun, 3 Dec 2023 15:43:04 +0100 Subject: [PATCH 015/257] Add support for VT_UI8 OLE VARIANT type Convert it to and from wxULongLong, as just as we already convert between VT_I8 and wxLongLong. Closes #24115. --- src/msw/ole/oleutils.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/msw/ole/oleutils.cpp b/src/msw/ole/oleutils.cpp index 4a6c90ac0c..72f5b29cc8 100644 --- a/src/msw/ole/oleutils.cpp +++ b/src/msw/ole/oleutils.cpp @@ -299,7 +299,12 @@ WXDLLEXPORT bool wxConvertVariantToOle(const wxVariant& variant, VARIANTARG& ole oleVariant.vt = VT_I8; oleVariant.llVal = variant.GetLongLong().GetValue(); } -#endif + else if (type == wxT("ulonglong")) + { + oleVariant.vt = VT_UI8; + oleVariant.ullVal = variant.GetULongLong().GetValue(); + } +#endif // wxUSE_LONGLONG else if (type == wxT("char")) { oleVariant.vt=VT_I1; // Signed Char @@ -469,6 +474,9 @@ wxConvertOleToVariant(const VARIANTARG& oleVariant, wxVariant& variant, long fla case VT_I8: variant = wxLongLong(oleVariant.llVal); break; + case VT_UI8: + variant = wxULongLong(oleVariant.ullVal); + break; #endif // wxUSE_LONGLONG case VT_I4: From 96b5c1419bca0519d32688df7dc681ac5f52a2ae Mon Sep 17 00:00:00 2001 From: Christian Walther Date: Mon, 4 Dec 2023 12:03:24 +0100 Subject: [PATCH 016/257] Fix uniconizing hidden top level windows in wxMSW again A window that was iconized while hidden, then uniconized while still hidden would fail to show uniconized. The reason is that Iconize(false) failed to update m_showCmd. What determines whether that is needed is not whether Windows considers the window iconized but whether wxWidgets does. This was previously fixed in ef40bc3dae (Fix uniconizing hidden top level windows in wxMSW., 2012-08-05), see #14539, but was broken later by 3518f1a7d8 (Use a single wxTopLevelWindow::m_showCmd flag in wxMSW, 2018-06-22), so fix it again. Closes #24117. --- src/msw/toplevel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index 2930894a57..a5f93a3788 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -708,7 +708,7 @@ bool wxTopLevelWindowMSW::IsMaximized() const void wxTopLevelWindowMSW::Iconize(bool iconize) { - if ( iconize == MSWIsIconized() ) + if ( iconize == IsIconized() ) { // Do nothing, in particular don't restore non-iconized windows when // Iconize(false) is called as this would wrongly un-maximize them. From e9dd3952151ca8a6eb6f047a32676849c29a7525 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 7 Dec 2023 17:15:36 +0100 Subject: [PATCH 017/257] Make the bitmap drawn centred inside the wxStaticBitmap control under wxQt This the default behaviour under wxMSW and wxGTK3 ports. --- src/qt/statbmp.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/qt/statbmp.cpp b/src/qt/statbmp.cpp index 52ad0eafde..fdca00d07f 100644 --- a/src/qt/statbmp.cpp +++ b/src/qt/statbmp.cpp @@ -17,7 +17,11 @@ class wxQtStaticBmp : public wxQtEventSignalHandler< QLabel, wxStaticBitmap > { public: wxQtStaticBmp( wxWindow *parent, wxStaticBitmap *handler ): - wxQtEventSignalHandler< QLabel, wxStaticBitmap >( parent, handler ){} + wxQtEventSignalHandler< QLabel, wxStaticBitmap >( parent, handler ) + { + // For compatibility with wxMSW and wxGTK3 ports. + setAlignment( Qt::AlignCenter ); + } }; From d3bdf486b31bd06e7bb2d10d7776d3a37ee4b1ac Mon Sep 17 00:00:00 2001 From: ali kettab Date: Mon, 20 Nov 2023 13:34:25 +0100 Subject: [PATCH 018/257] Don't override Refresh() in wxStatusBar under wxQt This is not necessary and, more importantly, results in a crash if you try to recreate the status bar (which can be seen in the statbar example) Also remove leftover QList declaration --- include/wx/qt/statusbar.h | 4 ---- src/qt/statusbar.cpp | 8 -------- 2 files changed, 12 deletions(-) diff --git a/include/wx/qt/statusbar.h b/include/wx/qt/statusbar.h index 38a4eba722..55e4547a4e 100644 --- a/include/wx/qt/statusbar.h +++ b/include/wx/qt/statusbar.h @@ -13,8 +13,6 @@ class QLabel; class QStatusBar; -template < class T > class QList; - class WXDLLIMPEXP_CORE wxStatusBar : public wxStatusBarBase { public: @@ -31,8 +29,6 @@ public: virtual void SetMinHeight(int height) override; virtual int GetBorderX() const override; virtual int GetBorderY() const override; - virtual void Refresh( bool eraseBackground = true, - const wxRect *rect = nullptr ) override; QStatusBar *GetQStatusBar() const { return m_qtStatusBar; } QWidget *GetHandle() const override; diff --git a/src/qt/statusbar.cpp b/src/qt/statusbar.cpp index c87f3fbd2f..10b7ecfb29 100644 --- a/src/qt/statusbar.cpp +++ b/src/qt/statusbar.cpp @@ -94,14 +94,6 @@ void wxStatusBar::DoUpdateStatusText(int number) m_qtPanes[number]->setText( wxQtConvertString( m_panes[number].GetText() ) ); } -// Called each time number/size of panes changes -void wxStatusBar::Refresh( bool eraseBackground, const wxRect *rect ) -{ - UpdateFields(); - - wxWindow::Refresh( eraseBackground, rect ); -} - void wxStatusBar::Init() { m_qtStatusBar = nullptr; From 02610d5d4bcc9dffa4e2ad92ae6755b43423a62e Mon Sep 17 00:00:00 2001 From: ali kettab Date: Mon, 20 Nov 2023 13:46:19 +0100 Subject: [PATCH 019/257] Remove trivial Init() from wxStatusBar under wxQt --- include/wx/qt/statusbar.h | 5 ++--- src/qt/statusbar.cpp | 11 ----------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/include/wx/qt/statusbar.h b/include/wx/qt/statusbar.h index 55e4547a4e..447dcd7248 100644 --- a/include/wx/qt/statusbar.h +++ b/include/wx/qt/statusbar.h @@ -16,7 +16,7 @@ class QStatusBar; class WXDLLIMPEXP_CORE wxStatusBar : public wxStatusBarBase { public: - wxStatusBar(); + wxStatusBar() = default; wxStatusBar(wxWindow *parent, wxWindowID winid = wxID_ANY, long style = wxSTB_DEFAULT_STYLE, const wxString& name = wxASCII_STR(wxStatusBarNameStr)); @@ -37,10 +37,9 @@ protected: virtual void DoUpdateStatusText(int number) override; private: - void Init(); void UpdateFields(); - QStatusBar *m_qtStatusBar; + QStatusBar *m_qtStatusBar = nullptr; wxVector m_qtPanes; wxDECLARE_DYNAMIC_CLASS(wxStatusBar); diff --git a/src/qt/statusbar.cpp b/src/qt/statusbar.cpp index 10b7ecfb29..1c32ede0ad 100644 --- a/src/qt/statusbar.cpp +++ b/src/qt/statusbar.cpp @@ -31,16 +31,10 @@ wxQtStatusBar::wxQtStatusBar( wxWindow *parent, wxStatusBar *handler ) //============================================================================== -wxStatusBar::wxStatusBar() -{ - Init(); -} - wxStatusBar::wxStatusBar(wxWindow *parent, wxWindowID winid, long style, const wxString& name) { - Init(); Create( parent, winid, style, name ); } @@ -94,11 +88,6 @@ void wxStatusBar::DoUpdateStatusText(int number) m_qtPanes[number]->setText( wxQtConvertString( m_panes[number].GetText() ) ); } -void wxStatusBar::Init() -{ - m_qtStatusBar = nullptr; -} - void wxStatusBar::UpdateFields() { // is it a good idea to recreate all the panes every update? From 5c46947c57e0507faa44366863d69fffc7d84a9e Mon Sep 17 00:00:00 2001 From: ali kettab Date: Mon, 20 Nov 2023 16:11:31 +0100 Subject: [PATCH 020/257] Fix wxStatusBar with field controls under wxQt Postpone the creation of the QStatusBar fields until the first call to SetStatusText(). This is to account for any field control added by the user and also to avoid having to call UpdateFields() multiple times. wxSTB_ELLIPSIZE_XXX and wxSTB_SHOW_TIPS supports are also implemented now. The statbar sample is also updated: The OnSize() handler is removed because it doesn't do much. that is: it is defined to keep the bitmap centered in the status bar field it occupies if it is resized. but this is already done by the wxStaticBitmap control, at least under wxMSW, wxGTK3 and wxQt. --- include/wx/qt/statusbar.h | 4 +- samples/statbar/statbar.cpp | 15 +---- src/qt/statusbar.cpp | 130 +++++++++++++++++++++++++++++------- 3 files changed, 109 insertions(+), 40 deletions(-) diff --git a/include/wx/qt/statusbar.h b/include/wx/qt/statusbar.h index 447dcd7248..3aef7d675b 100644 --- a/include/wx/qt/statusbar.h +++ b/include/wx/qt/statusbar.h @@ -10,7 +10,6 @@ #include "wx/statusbr.h" -class QLabel; class QStatusBar; class WXDLLIMPEXP_CORE wxStatusBar : public wxStatusBarBase @@ -25,6 +24,7 @@ public: long style = wxSTB_DEFAULT_STYLE, const wxString& name = wxASCII_STR(wxStatusBarNameStr)); + virtual void SetStatusWidths(int n, const int widths_field[]) override; virtual bool GetFieldRect(int i, wxRect& rect) const override; virtual void SetMinHeight(int height) override; virtual int GetBorderX() const override; @@ -40,7 +40,7 @@ private: void UpdateFields(); QStatusBar *m_qtStatusBar = nullptr; - wxVector m_qtPanes; + std::vector m_qtPanes; wxDECLARE_DYNAMIC_CLASS(wxStatusBar); }; diff --git a/samples/statbar/statbar.cpp b/samples/statbar/statbar.cpp index b9ccd6f933..26d06db1b8 100644 --- a/samples/statbar/statbar.cpp +++ b/samples/statbar/statbar.cpp @@ -94,7 +94,6 @@ public: #if wxUSE_TIMER void OnTimer(wxTimerEvent& WXUNUSED(event)) { UpdateClock(); } #endif - void OnSize(wxSizeEvent& event); void OnToggleClock(wxCommandEvent& event); void OnIdle(wxIdleEvent& event); @@ -270,7 +269,6 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) wxEND_EVENT_TABLE() wxBEGIN_EVENT_TABLE(MyStatusBar, wxStatusBar) - EVT_SIZE(MyStatusBar::OnSize) #if wxUSE_CHECKBOX EVT_CHECKBOX(StatusBar_Checkbox, MyStatusBar::OnToggleClock) #endif @@ -939,6 +937,7 @@ MyStatusBar::MyStatusBar(wxWindow *parent, long style) #endif m_statbmp = new wxStaticBitmap(this, wxID_ANY, wxIcon(green_xpm)); + AddFieldControl(Field_Bitmap, m_statbmp); #if wxUSE_TIMER m_timer.Start(1000); @@ -964,18 +963,6 @@ MyStatusBar::~MyStatusBar() #endif } -void MyStatusBar::OnSize(wxSizeEvent& event) -{ - wxRect rect; - GetFieldRect(Field_Bitmap, rect); - wxSize size = m_statbmp->GetSize(); - - m_statbmp->Move(rect.x + (rect.width - size.x) / 2, - rect.y + (rect.height - size.y) / 2); - - event.Skip(); -} - void MyStatusBar::OnToggleClock(wxCommandEvent& WXUNUSED(event)) { DoToggle(); diff --git a/src/qt/statusbar.cpp b/src/qt/statusbar.cpp index 1c32ede0ad..4b8ceff23f 100644 --- a/src/qt/statusbar.cpp +++ b/src/qt/statusbar.cpp @@ -50,17 +50,56 @@ bool wxStatusBar::Create(wxWindow *parent, wxWindowID WXUNUSED(winid), SetFieldsCount(1); + // Notice that child controls, if any, will be added using addWidget() in + // UpdateFields() function. So Unbind the base class handler which is not + // needed here. And more importantely, it won't work properly either. + Unbind(wxEVT_SIZE, &wxStatusBar::OnSize, static_cast(this)); + + Bind(wxEVT_SIZE, [this](wxSizeEvent& event) + { + const int n = this->GetFieldsCount(); + for ( int i = 0; i < n; ++i ) + { + // Update ellipsized status texts. + this->DoUpdateStatusText(i); + } + + event.Skip(); + }); + return true; } +void wxStatusBar::SetStatusWidths(int number, const int widths[]) +{ + if ( number != (int)m_panes.GetCount() ) + return; + + if ( !m_qtPanes.empty() ) + { + int i = 0; + for ( auto pane : m_qtPanes ) + { + m_qtStatusBar->removeWidget(pane); + + // Do not delete user-added controls. + if ( !m_panes[i++].GetFieldControl() ) + { + delete pane; + } + } + + m_qtPanes.clear(); + } + + wxStatusBarBase::SetStatusWidths(number, widths); +} + bool wxStatusBar::GetFieldRect(int i, wxRect& rect) const { wxCHECK_MSG( (i >= 0) && ((size_t)i < m_panes.GetCount()), false, "invalid statusbar field index" ); - if ( m_qtPanes.size() != m_panes.GetCount() ) - const_cast(this)->UpdateFields(); - rect = wxQtConvertRect(m_qtPanes[i]->geometry()); return true; } @@ -82,42 +121,85 @@ int wxStatusBar::GetBorderY() const void wxStatusBar::DoUpdateStatusText(int number) { - if ( m_qtPanes.size() != m_panes.GetCount() ) - UpdateFields(); + UpdateFields(); - m_qtPanes[number]->setText( wxQtConvertString( m_panes[number].GetText() ) ); + const auto pane = dynamic_cast(m_qtPanes[number]); + + if ( !pane ) + { + // do nothing if this pane is a field control. + return; + } + + QString text = wxQtConvertString( m_panes[number].GetText() ); + + // do we need to ellipsize this string? + Qt::TextElideMode ellmode = Qt::ElideNone; + if ( HasFlag(wxSTB_ELLIPSIZE_START) ) ellmode = Qt::ElideLeft; + else if ( HasFlag(wxSTB_ELLIPSIZE_MIDDLE) ) ellmode = Qt::ElideMiddle; + else if ( HasFlag(wxSTB_ELLIPSIZE_END) ) ellmode = Qt::ElideRight; + + if ( ellmode != Qt::ElideNone ) + { + QFontMetrics metrics(pane->font()); + QString elidedText = metrics.elidedText(text, ellmode, pane->width()); + + if ( HasFlag(wxSTB_SHOW_TIPS) ) + { + elidedText != text ? pane->setToolTip(text) : pane->setToolTip(QString()); + } + + text = elidedText; + } + + pane->setText(text); } void wxStatusBar::UpdateFields() { - // is it a good idea to recreate all the panes every update? + if ( !m_qtPanes.empty() ) + return; - for ( wxVector::const_iterator it = m_qtPanes.begin(); - it != m_qtPanes.end(); ++it ) - { - //Remove all panes - delete *it; - } - m_qtPanes.clear(); - - for (size_t i = 0; i < m_panes.GetCount(); i++) + for ( size_t i = 0; i < m_panes.GetCount(); ++i ) { //Set sizes - int width = m_panes[i].GetWidth(); + const int width = m_bSameWidthForAllPanes ? -1 : m_panes[i].GetWidth(); - QLabel *pane = new QLabel( m_qtStatusBar ); - m_qtPanes.push_back(pane); + QWidget* pane; + wxWindow* win = m_panes[i].GetFieldControl(); - if ( width >= 0 ) + if ( win ) { - //Fixed width field - pane->setMinimumSize( QSize(width, 0) ); - m_qtStatusBar->addWidget( pane ); + pane = win->GetHandle(); } else { - m_qtStatusBar->addWidget( pane, -width ); + pane = new QLabel; + if ( width >= 0 ) + pane->setMinimumWidth(width); + + int style; + switch( m_panes[i].GetStyle() ) + { + case wxSB_RAISED: + style = QFrame::Panel | QFrame::Raised; + break; + case wxSB_SUNKEN: + style = QFrame::Panel | QFrame::Sunken; + break; + case wxSB_NORMAL: + case wxSB_FLAT: + default: + style = QFrame::Plain | QFrame::NoFrame; + break; + } + + static_cast(pane)->setFrameStyle(style); } + + m_qtPanes.push_back(pane); + + m_qtStatusBar->addWidget(pane, width < 0 ? -width : 0); } } From c2cb80148d37360c5135530fd35ecce4e67a5cb1 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Mon, 20 Nov 2023 17:03:08 +0100 Subject: [PATCH 021/257] Fix parent/child relationship between the wxFrame and wxStatusBar under wxQt This also fixes wxEVT_IDLE events not delivered to the wxStatusBar. because it was not counted as a child of the frame it was added to. --- src/qt/statusbar.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/qt/statusbar.cpp b/src/qt/statusbar.cpp index 4b8ceff23f..750b323ec3 100644 --- a/src/qt/statusbar.cpp +++ b/src/qt/statusbar.cpp @@ -38,11 +38,15 @@ wxStatusBar::wxStatusBar(wxWindow *parent, wxWindowID winid, Create( parent, winid, style, name ); } -bool wxStatusBar::Create(wxWindow *parent, wxWindowID WXUNUSED(winid), - long style, const wxString& WXUNUSED(name)) +bool wxStatusBar::Create(wxWindow *parent, wxWindowID id, + long style, const wxString& name) { m_qtStatusBar = new wxQtStatusBar( parent, this ); + if ( !QtCreateControl( parent, id, wxDefaultPosition, wxDefaultSize, + style, wxDefaultValidator, name ) ) + return false; + if ( style & wxSTB_SIZEGRIP ) m_qtStatusBar->setSizeGripEnabled(true); From e758d8ad80a83fe30e6ff2bae0e15653e7c32402 Mon Sep 17 00:00:00 2001 From: Rick Date: Wed, 6 Dec 2023 11:52:45 +0100 Subject: [PATCH 022/257] Fix crash when processing renames in wxMSW wxFileSystemWatcher It could (and did, albeit rarely) happen that we read only the first of the couple events associated with a file rename and in this case the code crashed due to dereferencing invalid iterator. Ideal would be to delay sending the "renamed" event until we get the new path, but for now just fix the crash by not using the invalid iterator. Closes #24119. --- src/msw/fswatcher.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/msw/fswatcher.cpp b/src/msw/fswatcher.cpp index 6057ecc138..165a8948f3 100644 --- a/src/msw/fswatcher.cpp +++ b/src/msw/fswatcher.cpp @@ -349,6 +349,8 @@ void wxIOCPThread::ProcessNativeEvents(wxVector& events) } wxFileSystemWatcherEvent event(flags, oldpath, newpath); SendEvent(event); + if ( it == events.end() ) + break; } // all other events else From ce94e1d8b6d11fcfbde7f7f465a33a8d7e4bb1cf Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 8 Dec 2023 03:03:46 +0100 Subject: [PATCH 023/257] Don't use TABs in assert stack trace This string is shown in a message dialog which doesn't interpret TABs under all platforms, notably under Mac, making this string unreadable as the file names were not separated from the function names. Just use (enough) spaces instead and also increase the length of the function names as the full names can be very long in C++. --- src/common/appbase.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/common/appbase.cpp b/src/common/appbase.cpp index 1de2d9c468..b8d912b8bd 100644 --- a/src/common/appbase.cpp +++ b/src/common/appbase.cpp @@ -1023,19 +1023,18 @@ wxString wxAppTraitsBase::GetAssertStackTrace() if ( !name.empty() ) { - m_stackTrace << wxString::Format(wxT("%-40s"), name.c_str()); + m_stackTrace << wxString::Format("%-80s", name); } else { - m_stackTrace << wxString::Format(wxT("%p"), frame.GetAddress()); + m_stackTrace << wxString::Format("%-80p", frame.GetAddress()); } if ( frame.HasSourceLocation() ) { - m_stackTrace << wxT('\t') - << frame.GetFileName() - << wxT(':') - << frame.GetLine(); + m_stackTrace << wxString::Format("%s:%zu", + frame.GetFileName(), + frame.GetLine()); } m_stackTrace << wxT('\n'); From 3af16cd0637061789e35545b08781aa063488957 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Fri, 8 Dec 2023 08:25:40 -0800 Subject: [PATCH 024/257] Ensure wxListBox best size is at least the minimum required by GTK3 And remove unnecessary SetInitialSize(), PostCreation() already does that. Avoids a Gtk-CRITICAL assertion 'size >= 0' failed in GtkScrollbar --- src/gtk/listbox.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index 53d4be47e6..50950df161 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -378,7 +378,6 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, m_parent->DoAddChild( this ); PostCreation(size); - SetInitialSize(size); // need this too because this is a wxControlWithItems g_signal_connect_after (selection, "changed", G_CALLBACK (gtk_listitem_changed_callback), this); @@ -936,7 +935,15 @@ wxSize wxListBox::DoGetBestSize() const // Don't make the listbox too tall but don't make it too small either lbHeight = (cy+4) * wxMin(wxMax(count, 3), 10); - return wxSize(lbWidth, lbHeight); + wxSize size(lbWidth, lbHeight); +#ifdef __WXGTK3__ + // Ensure size is at least the required minimum + wxSize min; + gtk_widget_get_preferred_width(m_widget, &min.x, nullptr); + gtk_widget_get_preferred_height_for_width(m_widget, min.x, &min.y, nullptr); + size.IncTo(min); +#endif + return size; } // static From f667f765eb052e739a3ac706fc4f24c09714e5ae Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 10 Dec 2023 01:31:14 +0100 Subject: [PATCH 025/257] Initialize member variables in declaration in splitter sample No real changes, just make things a bit simpler and safer. --- samples/splitter/splitter.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/samples/splitter/splitter.cpp b/samples/splitter/splitter.cpp index 441ae97214..867e42cb16 100644 --- a/samples/splitter/splitter.cpp +++ b/samples/splitter/splitter.cpp @@ -126,13 +126,14 @@ public: int GetSashPos() const { return m_sashPos; } private: - wxWindow *m_left, *m_right; + wxWindow *m_left = nullptr, + *m_right = nullptr; - wxSplitterWindow* m_splitter; - wxWindow *m_replacewindow; - int m_sashPos; - bool m_lockSash; - bool m_allowDClick; + wxSplitterWindow* m_splitter = nullptr; + wxWindow *m_replacewindow = nullptr; + int m_sashPos = 0; + bool m_lockSash = false; + bool m_allowDClick = true; wxDECLARE_EVENT_TABLE(); wxDECLARE_NO_COPY_CLASS(MyFrame); @@ -228,10 +229,6 @@ MyFrame::MyFrame() : wxFrame(nullptr, wxID_ANY, "wxSplitterWindow sample", wxDefaultPosition, wxSize(420, 300)) { - m_lockSash = false; - m_sashPos = 0; - m_allowDClick = true; - SetIcon(wxICON(sample)); #if wxUSE_STATUSBAR @@ -340,8 +337,6 @@ MyFrame::MyFrame() #if wxUSE_STATUSBAR SetStatusText("Min pane size = 0", 1); #endif // wxUSE_STATUSBAR - - m_replacewindow = nullptr; } MyFrame::~MyFrame() From 375fd2c630019525746f23555a3b77974c531538 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Sat, 9 Dec 2023 18:17:53 -0800 Subject: [PATCH 026/257] Incorporate GTK preferred size into best size for non-native controls It may be better than the default GetBestSize() result. Fixes best size of wxStaticBox when children are narrower than label, and minimum size for controls using a scrolled window, such as wxTreeCtrl. --- src/gtk/control.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/gtk/control.cpp b/src/gtk/control.cpp index 8af81617a7..66be1fde65 100644 --- a/src/gtk/control.cpp +++ b/src/gtk/control.cpp @@ -78,15 +78,11 @@ wxSize wxControl::DoGetBestSize() const // Do not return any arbitrary default value... wxASSERT_MSG( m_widget, wxT("DoGetBestSize called before creation") ); - wxSize best; + wxSize best(GTKGetPreferredSize(m_widget)); if (m_wxwindow) { - // this is not a native control, size_request is likely to be (0,0) - best = wxControlBase::DoGetBestSize(); - } - else - { - best = GTKGetPreferredSize(m_widget); + // For non-native controls, GTK preferred size may not be useful + best.IncTo(base_type::DoGetBestSize()); } return best; From c3d1618cc8e3011646d7fd1de96e89f1606e320a Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Sun, 10 Dec 2023 09:10:42 -0800 Subject: [PATCH 027/257] Fix transitory visual glitch with wxBORDER_NONE on GTK3 Changing the CSS after adding child to already-showing parent can cause a fleeting glimpse of the original style. See #24105 --- include/wx/gtk/checkbox.h | 2 ++ include/wx/gtk/control.h | 2 ++ include/wx/gtk/window.h | 1 + src/gtk/checkbox.cpp | 20 ++++++-------------- src/gtk/control.cpp | 12 +++++++----- src/gtk/window.cpp | 9 +++++++++ 6 files changed, 27 insertions(+), 19 deletions(-) diff --git a/include/wx/gtk/checkbox.h b/include/wx/gtk/checkbox.h index c98615db7b..fdfa4a7b1e 100644 --- a/include/wx/gtk/checkbox.h +++ b/include/wx/gtk/checkbox.h @@ -59,6 +59,8 @@ protected: private: typedef wxCheckBoxBase base_type; + virtual void GTKRemoveBorder() override; + GtkWidget *m_widgetCheckbox; GtkWidget *m_widgetLabel; diff --git a/include/wx/gtk/control.h b/include/wx/gtk/control.h index 684c3a5f41..d6a7721955 100644 --- a/include/wx/gtk/control.h +++ b/include/wx/gtk/control.h @@ -87,6 +87,8 @@ protected: wxSize GTKGetEntryMargins(GtkEntry* entry) const; private: + virtual void GTKRemoveBorder() override; + wxDECLARE_DYNAMIC_CLASS(wxControl); }; diff --git a/include/wx/gtk/window.h b/include/wx/gtk/window.h index f0c94d8d2a..0b26076a09 100644 --- a/include/wx/gtk/window.h +++ b/include/wx/gtk/window.h @@ -466,6 +466,7 @@ protected: private: void Init(); + virtual void GTKRemoveBorder(); // return true if this window must have a non-null parent, false if it can // be created without parent (normally only top level windows but in wxGTK diff --git a/src/gtk/checkbox.cpp b/src/gtk/checkbox.cpp index e11a1144aa..06722a437f 100644 --- a/src/gtk/checkbox.cpp +++ b/src/gtk/checkbox.cpp @@ -141,25 +141,17 @@ bool wxCheckBox::Create(wxWindow *parent, m_parent->DoAddChild( this ); -#ifdef __WXGTK3__ - // CSS added if the window has wxNO_BORDER inside base class PostCreation() - // makes checkbox look broken in the default GTK 3 theme, so avoid doing - // this by temporarily turning this flag off. - if ( style & wxNO_BORDER ) - ToggleWindowStyle(wxNO_BORDER); -#endif - PostCreation(size); -#ifdef __WXGTK3__ - // Turn it back on if necessary. - if ( style & wxNO_BORDER ) - ToggleWindowStyle(wxNO_BORDER); -#endif - return true; } +void wxCheckBox::GTKRemoveBorder() +{ + // CSS added if the window has wxBORDER_NONE makes + // checkbox look broken in the default GTK 3 theme +} + void wxCheckBox::GTKDisableEvents() { g_signal_handlers_block_by_func(m_widgetCheckbox, diff --git a/src/gtk/control.cpp b/src/gtk/control.cpp index 66be1fde65..5787a26774 100644 --- a/src/gtk/control.cpp +++ b/src/gtk/control.cpp @@ -92,11 +92,6 @@ void wxControl::PostCreation(const wxSize& size) { wxWindow::PostCreation(); -#ifdef __WXGTK3__ - if (HasFlag(wxNO_BORDER)) - GTKApplyCssStyle("*{ border:none; border-radius:0; padding:0 }"); -#endif - #ifndef __WXGTK3__ // NB: GetBestSize needs to know the style, otherwise it will assume // default font and if the user uses a different font, determined @@ -109,6 +104,13 @@ void wxControl::PostCreation(const wxSize& size) SetInitialSize(size); } +void wxControl::GTKRemoveBorder() +{ +#ifdef __WXGTK3__ + GTKApplyCssStyle("*{ border:none; border-radius:0; padding:0 }"); +#endif +} + // ---------------------------------------------------------------------------- // Work around a GTK+ bug whereby button is insensitive after being // enabled diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index f6c7899c64..05f62a87da 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -4913,11 +4913,20 @@ bool wxWindowGTK::Reparent( wxWindowBase *newParentBase ) return true; } +void wxWindowGTK::GTKRemoveBorder() +{ +} + void wxWindowGTK::DoAddChild(wxWindowGTK *child) { wxASSERT_MSG( (m_widget != nullptr), wxT("invalid window") ); wxASSERT_MSG( (child != nullptr), wxT("invalid child window") ); + // If parent is already showing, changing CSS after adding child + // can cause transitory visual glitches, so change it here + if (HasFlag(wxBORDER_NONE)) + GTKRemoveBorder(); + /* add to list */ AddChild( child ); From 5ef4c1062a74ec31f9ae5f0701d5bc5d7ec716e3 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Sun, 10 Dec 2023 09:35:15 -0800 Subject: [PATCH 028/257] Replace zero-as-null with nullptr --- src/common/intl.cpp | 2 +- src/common/sckaddr.cpp | 18 +++++++++--------- src/common/zipstrm.cpp | 4 ++-- src/msw/brush.cpp | 2 +- src/msw/crashrpt.cpp | 2 +- src/msw/debughlp.cpp | 2 +- src/msw/dialup.cpp | 2 +- src/msw/dragimag.cpp | 2 +- src/msw/fswatcher.cpp | 4 ++-- src/msw/graphicsd2d.cpp | 2 +- src/msw/mediactrl_qt.cpp | 8 ++++---- src/msw/stackwalk.cpp | 2 +- src/msw/thread.cpp | 2 +- src/msw/tooltip.cpp | 4 ++-- src/msw/window.cpp | 2 +- src/unix/mediactrl_gstplayer.cpp | 2 +- 16 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/common/intl.cpp b/src/common/intl.cpp index 2e746cf8c6..9bc8513c47 100644 --- a/src/common/intl.cpp +++ b/src/common/intl.cpp @@ -1248,7 +1248,7 @@ wxString wxLocale::GetOSInfo(wxLocaleInfo index, wxLocaleCategory cat) extern wxString wxGetInfoFromCFLocale(CFLocaleRef cfloc, wxLocaleInfo index, wxLocaleCategory WXUNUSED(cat)) { - CFStringRef cfstr = 0; + CFStringRef cfstr = nullptr; switch ( index ) { case wxLOCALE_THOUSANDS_SEP: diff --git a/src/common/sckaddr.cpp b/src/common/sckaddr.cpp index fe09238ca4..0262365ca4 100644 --- a/src/common/sckaddr.cpp +++ b/src/common/sckaddr.cpp @@ -203,11 +203,11 @@ hostent *deepCopyHostent(hostent *h, /* leave space for pointer list */ char **p = h->h_addr_list, **q; char **h_addr_list = (char **)(buffer + pos); - while(*(p++) != 0) + while(*(p++) != nullptr) pos += sizeof(char *); /* copy addresses and fill new pointer list */ - for (p = h->h_addr_list, q = h_addr_list; *p != 0; p++, q++) + for (p = h->h_addr_list, q = h_addr_list; *p != nullptr; p++, q++) { if (size < pos + len) { @@ -218,7 +218,7 @@ hostent *deepCopyHostent(hostent *h, *q = buffer + pos; /* set copied pointer to copied content */ pos += len; } - *++q = 0; /* null terminate the pointer list */ + *++q = nullptr; /* null terminate the pointer list */ h->h_addr_list = h_addr_list; /* copy pointer to pointers */ /* ensure word alignment of pointers */ @@ -229,11 +229,11 @@ hostent *deepCopyHostent(hostent *h, /* leave space for pointer list */ p = h->h_aliases; char **h_aliases = (char **)(buffer + pos); - while(*(p++) != 0) + while(*(p++) != nullptr) pos += sizeof(char *); /* copy aliases and fill new pointer list */ - for (p = h->h_aliases, q = h_aliases; *p != 0; p++, q++) + for (p = h->h_aliases, q = h_aliases; *p != nullptr; p++, q++) { len = strlen(*p); if (size <= pos + len) @@ -246,7 +246,7 @@ hostent *deepCopyHostent(hostent *h, *q = buffer + pos; /* set copied pointer to copied content */ pos += len + 1; } - *++q = 0; /* null terminate the pointer list */ + *++q = nullptr; /* null terminate the pointer list */ h->h_aliases = h_aliases; /* copy pointer to pointers */ return h; @@ -358,11 +358,11 @@ servent *deepCopyServent(servent *s, /* leave space for pointer list */ char **p = s->s_aliases, **q; char **s_aliases = (char **)(buffer + pos); - while(*(p++) != 0) + while(*(p++) != nullptr) pos += sizeof(char *); /* copy addresses and fill new pointer list */ - for (p = s->s_aliases, q = s_aliases; *p != 0; p++, q++){ + for (p = s->s_aliases, q = s_aliases; *p != nullptr; p++, q++){ len = strlen(*p); if (size <= pos + len) { @@ -373,7 +373,7 @@ servent *deepCopyServent(servent *s, *q = buffer + pos; /* set copied pointer to copied content */ pos += len + 1; } - *++q = 0; /* null terminate the pointer list */ + *++q = nullptr; /* null terminate the pointer list */ s->s_aliases = s_aliases; /* copy pointer to pointers */ return s; } diff --git a/src/common/zipstrm.cpp b/src/common/zipstrm.cpp index 1f7fa388a6..6393596de0 100644 --- a/src/common/zipstrm.cpp +++ b/src/common/zipstrm.cpp @@ -2016,7 +2016,7 @@ bool wxZipInputStream::OpenDecompressor(bool raw /*=false*/) } } - m_crcAccumulator = crc32(0, Z_NULL, 0); + m_crcAccumulator = crc32(0, nullptr, 0); m_lasterror = m_decomp ? m_decomp->GetLastError() : wxSTREAM_READ_ERROR; return IsOk(); } @@ -2296,7 +2296,7 @@ bool wxZipOutputStream::DoCreate(wxZipEntry *entry, bool raw /*=false*/) m_pending->SetOffset(m_headerOffset); - m_crcAccumulator = crc32(0, Z_NULL, 0); + m_crcAccumulator = crc32(0, nullptr, 0); if (raw) m_raw = true; diff --git a/src/msw/brush.cpp b/src/msw/brush.cpp index 3c07666f0c..f1cfe69048 100644 --- a/src/msw/brush.cpp +++ b/src/msw/brush.cpp @@ -282,7 +282,7 @@ wxBitmap *wxBrush::GetStipple() const WXHANDLE wxBrush::GetResourceHandle() const { - wxCHECK_MSG( IsOk(), FALSE, wxT("invalid brush") ); + wxCHECK_MSG( IsOk(), nullptr, wxT("invalid brush") ); return (WXHANDLE)M_BRUSHDATA->GetHBRUSH(); } diff --git a/src/msw/crashrpt.cpp b/src/msw/crashrpt.cpp index 9d4cd22c08..1b591451db 100644 --- a/src/msw/crashrpt.cpp +++ b/src/msw/crashrpt.cpp @@ -129,7 +129,7 @@ void wxCrashReportImpl::Output(const wxChar *format, ...) wxString s = wxString::FormatV(format, argptr); wxCharBuffer buf(s.mb_str(wxConvUTF8)); - ::WriteFile(m_hFile, buf.data(), strlen(buf.data()), &cbWritten, 0); + ::WriteFile(m_hFile, buf.data(), strlen(buf.data()), &cbWritten, nullptr); va_end(argptr); } diff --git a/src/msw/debughlp.cpp b/src/msw/debughlp.cpp index 1dd33a5d6a..a4495401a7 100644 --- a/src/msw/debughlp.cpp +++ b/src/msw/debughlp.cpp @@ -105,7 +105,7 @@ static wxString gs_errMsg; // ---------------------------------------------------------------------------- #define DEFINE_SYM_FUNCTION(func, name) \ - wxDbgHelpDLL::func ## _t wxDbgHelpDLL::func = 0 + wxDbgHelpDLL::func ## _t wxDbgHelpDLL::func = nullptr wxDO_FOR_ALL_SYM_FUNCS(DEFINE_SYM_FUNCTION); diff --git a/src/msw/dialup.cpp b/src/msw/dialup.cpp index c7547df737..6aeba14b34 100644 --- a/src/msw/dialup.cpp +++ b/src/msw/dialup.cpp @@ -815,7 +815,7 @@ bool wxDialUpManagerMSW::Dial(const wxString& nameOfISP, &rasDialParams, 0, // use callback for notifications async ? (void *)wxRasDialFunc // cast needed for gcc 3.1 - : 0, // no notifications, sync operation + : nullptr, // no notifications, sync operation &ms_hRasConnection ); diff --git a/src/msw/dragimag.cpp b/src/msw/dragimag.cpp index b62a027911..51c8e0f209 100644 --- a/src/msw/dragimag.cpp +++ b/src/msw/dragimag.cpp @@ -113,7 +113,7 @@ bool wxDragImage::Create(const wxBitmap& image, const wxCursor& cursor) else flags = ILC_COLOR32; - bool mask = (image.GetMask() != 0); + bool mask = image.GetMask() != nullptr; // Curiously, even if the image doesn't have a mask, // we still have to use ILC_MASK or the image won't show diff --git a/src/msw/fswatcher.cpp b/src/msw/fswatcher.cpp index 165a8948f3..11fd4a9652 100644 --- a/src/msw/fswatcher.cpp +++ b/src/msw/fswatcher.cpp @@ -62,7 +62,7 @@ wxFSWatcherImplMSW::~wxFSWatcherImplMSW() { // order the worker thread to finish & wait m_workerThread.Finish(); - if (m_workerThread.Wait() != 0) + if (m_workerThread.Wait()) { wxLogError(_("Ungraceful worker thread termination")); } @@ -210,7 +210,7 @@ wxThread::ExitCode wxIOCPThread::Entry() while ( ReadEvents() ); wxLogTrace(wxTRACE_FSWATCHER, "[iocp] Ended IOCP thread"); - return (ExitCode)0; + return nullptr; } // wait for events to occur, read them and send to interested parties diff --git a/src/msw/graphicsd2d.cpp b/src/msw/graphicsd2d.cpp index 7d31c0c5d4..6faaa4e6de 100644 --- a/src/msw/graphicsd2d.cpp +++ b/src/msw/graphicsd2d.cpp @@ -2593,7 +2593,7 @@ public: protected: void DoAcquireResource() override { - HRESULT hr = GetContext()->CreateBitmapFromWicBitmap(m_srcBitmap, 0, &m_nativeResource); + HRESULT hr = GetContext()->CreateBitmapFromWicBitmap(m_srcBitmap, nullptr, &m_nativeResource); wxCHECK_HRESULT_RET(hr); } diff --git a/src/msw/mediactrl_qt.cpp b/src/msw/mediactrl_qt.cpp index 06773ad699..11334ac77b 100644 --- a/src/msw/mediactrl_qt.cpp +++ b/src/msw/mediactrl_qt.cpp @@ -236,14 +236,14 @@ public: wxDL_VOIDMETHOD_DEFINE(SetMovieBox, (Movie m, Rect* r), (m,r)) wxDL_VOIDMETHOD_DEFINE(SetMovieTimeScale, (Movie m, long s), (m,s)) wxDL_METHOD_DEFINE(long, GetMovieDuration, (Movie m), (m), 0) - wxDL_METHOD_DEFINE(TimeBase, GetMovieTimeBase, (Movie m), (m), 0) + wxDL_METHOD_DEFINE(TimeBase, GetMovieTimeBase, (Movie m), (m), nullptr) wxDL_METHOD_DEFINE(TimeScale, GetMovieTimeScale, (Movie m), (m), 0) wxDL_METHOD_DEFINE(long, GetMovieTime, (Movie m, void* cruft), (m,cruft), 0) wxDL_VOIDMETHOD_DEFINE(SetMovieTime, (Movie m, TimeRecord* tr), (m,tr) ) wxDL_METHOD_DEFINE(short, GetMovieVolume, (Movie m), (m), 0) wxDL_VOIDMETHOD_DEFINE(SetMovieVolume, (Movie m, short sVolume), (m,sVolume) ) wxDL_VOIDMETHOD_DEFINE(SetMovieTimeValue, (Movie m, long s), (m,s)) - wxDL_METHOD_DEFINE(ComponentInstance, NewMovieController, (Movie m, const Rect* mr, long fl), (m,mr,fl), 0) + wxDL_METHOD_DEFINE(ComponentInstance, NewMovieController, (Movie m, const Rect* mr, long fl), (m,mr,fl), nullptr) wxDL_VOIDMETHOD_DEFINE(DisposeMovieController, (ComponentInstance ci), (ci)) wxDL_METHOD_DEFINE(int, MCSetVisible, (ComponentInstance m, int b), (m, b), 0) @@ -251,9 +251,9 @@ public: wxDL_VOIDMETHOD_DEFINE(PrerollMovie, (Movie m, long t, Fixed r), (m,t,r) ) wxDL_METHOD_DEFINE(Fixed, GetMoviePreferredRate, (Movie m), (m), 0) wxDL_METHOD_DEFINE(long, GetMovieLoadState, (Movie m), (m), 0) - wxDL_METHOD_DEFINE(void*, NewRoutineDescriptor, (WXFARPROC f, int l, void* junk), (f, l, junk), 0) + wxDL_METHOD_DEFINE(void*, NewRoutineDescriptor, (WXFARPROC f, int l, void* junk), (f, l, junk), nullptr) wxDL_VOIDMETHOD_DEFINE(DisposeRoutineDescriptor, (void* f), (f)) - wxDL_METHOD_DEFINE(void*, GetCurrentArchitecture, (), (), 0) + wxDL_METHOD_DEFINE(void*, GetCurrentArchitecture, (), (), nullptr) wxDL_METHOD_DEFINE(int, MCDoAction, (ComponentInstance ci, long f, void* p), (ci,f,p), 0) wxDL_VOIDMETHOD_DEFINE(MCSetControllerBoundsRect, (ComponentInstance ci, Rect* r), (ci,r)) wxDL_VOIDMETHOD_DEFINE(DestroyPortAssociation, (CGrafPtr g), (g)) diff --git a/src/msw/stackwalk.cpp b/src/msw/stackwalk.cpp index 98d514bf74..eb9fc167ae 100644 --- a/src/msw/stackwalk.cpp +++ b/src/msw/stackwalk.cpp @@ -153,7 +153,7 @@ void wxStackFrame::OnGetParam() ( ::GetCurrentProcess(), &imagehlpStackFrame, - 0 // unused + nullptr // unused ) ) { // for symbols from kernel DLL we might not have access to their diff --git a/src/msw/thread.cpp b/src/msw/thread.cpp index 8bd3364efb..df1d343e3c 100644 --- a/src/msw/thread.cpp +++ b/src/msw/thread.cpp @@ -1340,7 +1340,7 @@ bool wxThreadModule::OnInit() // main thread doesn't have associated wxThread object, so store 0 in the // TLS instead - if ( !::TlsSetValue(gs_tlsThisThread, (LPVOID)0) ) + if ( !::TlsSetValue(gs_tlsThisThread, nullptr) ) { ::TlsFree(gs_tlsThisThread); gs_tlsThisThread = TLS_OUT_OF_INDEXES; diff --git a/src/msw/tooltip.cpp b/src/msw/tooltip.cpp index a9d0eb7ab9..17edcda974 100644 --- a/src/msw/tooltip.cpp +++ b/src/msw/tooltip.cpp @@ -571,7 +571,7 @@ bool wxToolTip::AdjustMaxWidth() // use TTM_SETMAXTIPWIDTH to make tooltip multiline using the // extent of its first line as max value HFONT hfont = (HFONT) - SendTooltipMessage(GetToolTipCtrl(), WM_GETFONT, 0); + SendTooltipMessage(GetToolTipCtrl(), WM_GETFONT, nullptr); if ( !hfont ) { @@ -631,7 +631,7 @@ bool wxToolTip::AdjustMaxWidth() // one would result in breaking the longer lines unnecessarily as // all our tooltips share the same maximal width if ( maxWidth > SendTooltipMessage(GetToolTipCtrl(), - TTM_GETMAXTIPWIDTH, 0) ) + TTM_GETMAXTIPWIDTH, nullptr) ) { SendTooltipMessage(GetToolTipCtrl(), TTM_SETMAXTIPWIDTH, wxUIntToPtr(maxWidth)); diff --git a/src/msw/window.cpp b/src/msw/window.cpp index d12dd5f19d..b3c813dae8 100644 --- a/src/msw/window.cpp +++ b/src/msw/window.cpp @@ -4503,7 +4503,7 @@ bool wxWindowMSW::HandleDropFiles(WXWPARAM wParam) ( (HDROP)hFilesInfo, (UINT)-1, - (LPTSTR)0, + nullptr, (UINT)0 ); diff --git a/src/unix/mediactrl_gstplayer.cpp b/src/unix/mediactrl_gstplayer.cpp index 3be6dc3227..bda3b9305b 100644 --- a/src/unix/mediactrl_gstplayer.cpp +++ b/src/unix/mediactrl_gstplayer.cpp @@ -222,7 +222,7 @@ static void realize_callback(GtkWidget* widget, wxGStreamerMediaBackend* be) #endif // wxGTK wxGStreamerMediaBackend::wxGStreamerMediaBackend() - : m_player(0), m_video_renderer(0), m_videoSize(0, 0), m_last_state(wxMEDIASTATE_STOPPED), m_loaded(false) + : m_player(nullptr), m_video_renderer(nullptr), m_videoSize(0, 0), m_last_state(wxMEDIASTATE_STOPPED), m_loaded(false) { } From d4b5c21de74e007e63be19323c02cd7e947399a4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 8 Dec 2023 03:05:20 +0100 Subject: [PATCH 029/257] Fix compile-time check for macOS 11 This fixes warnings about MAC_OS_X_VERSION_11_0 not being defined when using older SDKs, as 21da0e128d (Change wxRendererNative to use NSCell-based methods under Mac, 2023-11-12) used a wrong name for the version constant: since macOS 11 these constants don't use "X" in their names any longer. Remove this and add a comment to the place where we define them to document this not quite obvious naming convention. --- include/wx/platform.h | 3 +++ src/osx/cocoa/renderer.mm | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/wx/platform.h b/include/wx/platform.h index b77b5bd86c..8597797767 100644 --- a/include/wx/platform.h +++ b/include/wx/platform.h @@ -455,6 +455,9 @@ # ifndef MAC_OS_X_VERSION_10_16 # define MAC_OS_X_VERSION_10_16 101600 # endif + /* + Note that since macOS 11 there is no more "X" in the names. + */ # ifndef MAC_OS_VERSION_11_0 # define MAC_OS_VERSION_11_0 110000 # endif diff --git a/src/osx/cocoa/renderer.mm b/src/osx/cocoa/renderer.mm index 1fe4a98b0b..484de678ee 100644 --- a/src/osx/cocoa/renderer.mm +++ b/src/osx/cocoa/renderer.mm @@ -618,7 +618,7 @@ void wxRendererMac::ApplyMacControlFlags(wxWindow* win, NSCell* cell, int flags) size = NSSmallControlSize; else if (win->GetWindowVariant() == wxWINDOW_VARIANT_MINI || (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_MINI)) size = NSMiniControlSize; -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_11_0 +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0 else if (win->GetWindowVariant() == wxWINDOW_VARIANT_LARGE|| (win->GetParent() && win->GetParent()->GetWindowVariant() == wxWINDOW_VARIANT_LARGE)) { if (WX_IS_MACOS_AVAILABLE(11, 0)) From 5dffb76d0a4e15bcede71748e3edee478bf61d73 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 8 Dec 2023 03:08:49 +0100 Subject: [PATCH 030/257] Remove bool parameter from MacSetClipChildren() This parameter was always "true" in the existing calls to this function and the underlying UseClippingView() didn't support passing "false" to it anyhow, so it seems simpler and more clear to just remove the parameter. It also avoids clang warnings about it being unused. No real changes. --- include/wx/osx/cocoa/private.h | 2 +- include/wx/osx/core/private.h | 2 +- include/wx/osx/window.h | 2 +- include/wx/scrolwin.h | 2 +- src/generic/datavgen.cpp | 2 +- src/generic/laywin.cpp | 2 +- src/generic/scrlwing.cpp | 2 +- src/generic/vscroll.cpp | 2 +- src/osx/cocoa/window.mm | 2 +- src/osx/window_osx.cpp | 10 +++++----- 10 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index add141eb0e..22b9b0d52a 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -221,7 +221,7 @@ public : virtual void controlTextDidChange(); virtual void AdjustClippingView(wxScrollBar* horizontal, wxScrollBar* vertical) override; - virtual void UseClippingView(bool clip) override; + virtual void UseClippingView() override; virtual WXWidget GetContainer() const override { return m_osxClipView ? m_osxClipView : m_osxView; } protected: diff --git a/include/wx/osx/core/private.h b/include/wx/osx/core/private.h index 6c16eaf783..f4c478497a 100644 --- a/include/wx/osx/core/private.h +++ b/include/wx/osx/core/private.h @@ -368,7 +368,7 @@ public : // scrolling views need a clip subview that acts as parent for native children // (except for the scollbars) which are children of the view itself virtual void AdjustClippingView(wxScrollBar* horizontal, wxScrollBar* vertical); - virtual void UseClippingView(bool clip); + virtual void UseClippingView(); // returns native view which acts as a parent for native children virtual WXWidget GetContainer() const; diff --git a/include/wx/osx/window.h b/include/wx/osx/window.h index e19241d430..a5f5e2c359 100644 --- a/include/wx/osx/window.h +++ b/include/wx/osx/window.h @@ -224,7 +224,7 @@ public: // returns true if children have to clipped to the content area // (e.g., scrolled windows) bool MacClipChildren() const { return m_clipChildren ; } - void MacSetClipChildren( bool clip ); + void MacSetClipChildren(); // returns true if the grandchildren need to be clipped to the children's content area // (e.g., splitter windows) diff --git a/include/wx/scrolwin.h b/include/wx/scrolwin.h index c612997aab..abedfb8e44 100644 --- a/include/wx/scrolwin.h +++ b/include/wx/scrolwin.h @@ -439,7 +439,7 @@ public: m_targetWindow = this; #ifdef __WXMAC__ - this->MacSetClipChildren(true); + this->MacSetClipChildren(); #endif // by default, we're scrollable in both directions (but if one of the diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 437c9943fb..f5e111e519 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -5641,7 +5641,7 @@ bool wxDataViewCtrl::Create(wxWindow *parent, SetInitialSize(size); #ifdef __WXMAC__ - MacSetClipChildren( true ); + MacSetClipChildren(); #endif m_clientArea = new wxDataViewMainWindow( this, wxID_ANY ); diff --git a/src/generic/laywin.cpp b/src/generic/laywin.cpp index 1564b3a3f7..9367b14fea 100644 --- a/src/generic/laywin.cpp +++ b/src/generic/laywin.cpp @@ -50,7 +50,7 @@ void wxSashLayoutWindow::Init() m_orientation = wxLAYOUT_HORIZONTAL; m_alignment = wxLAYOUT_TOP; #ifdef __WXMAC__ - MacSetClipChildren( true ) ; + MacSetClipChildren() ; #endif } diff --git a/src/generic/scrlwing.cpp b/src/generic/scrlwing.cpp index 4f347509be..bcfb096d84 100644 --- a/src/generic/scrlwing.cpp +++ b/src/generic/scrlwing.cpp @@ -444,7 +444,7 @@ void wxScrollHelperBase::DoSetTargetWindow(wxWindow *target) { m_targetWindow = target; #ifdef __WXMAC__ - target->MacSetClipChildren( true ) ; + target->MacSetClipChildren() ; #endif // install the event handler which will intercept the events we're diff --git a/src/generic/vscroll.cpp b/src/generic/vscroll.cpp index 66db08c8eb..2f14570630 100644 --- a/src/generic/vscroll.cpp +++ b/src/generic/vscroll.cpp @@ -435,7 +435,7 @@ void wxVarScrollHelperBase::DoSetTargetWindow(wxWindow *target) { m_targetWindow = target; #ifdef __WXMAC__ - target->MacSetClipChildren( true ) ; + target->MacSetClipChildren() ; #endif // install the event handler which will intercept the events we're diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index d8e863bce1..e827553f05 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -4077,7 +4077,7 @@ void wxWidgetCocoaImpl::AdjustClippingView(wxScrollBar* horizontal, wxScrollBar* } } -void wxWidgetCocoaImpl::UseClippingView(bool clip) +void wxWidgetCocoaImpl::UseClippingView() { wxWindow* peer = m_wxPeer; diff --git a/src/osx/window_osx.cpp b/src/osx/window_osx.cpp index 448e360bb7..3c3eceac8f 100644 --- a/src/osx/window_osx.cpp +++ b/src/osx/window_osx.cpp @@ -261,11 +261,11 @@ wxWindowMac::~wxWindowMac() delete GetPeer() ; } -void wxWindowMac::MacSetClipChildren( bool clip ) +void wxWindowMac::MacSetClipChildren() { - m_clipChildren = clip ; + m_clipChildren = true ; if ( m_peer ) - m_peer->UseClippingView(clip); + m_peer->UseClippingView(); } WXWidget wxWindowMac::GetHandle() const @@ -394,7 +394,7 @@ bool wxWindowMac::Create(wxWindowMac *parent, SetPeer(wxWidgetImpl::CreateUserPane( this, parent, id, pos, size , style, GetExtraStyle() )); MacPostControlCreate(pos, size) ; if ( m_clipChildren ) - m_peer->UseClippingView(m_clipChildren); + m_peer->UseClippingView(); } wxWindowCreateEvent event((wxWindow*)this); @@ -2715,7 +2715,7 @@ void wxWidgetImpl::AdjustClippingView(wxScrollBar* WXUNUSED(horizontal), wxScrol { } -void wxWidgetImpl::UseClippingView(bool WXUNUSED(clip)) +void wxWidgetImpl::UseClippingView() { } From bc19ed83878ce32cf22a9a415dfbaf366ec7ff87 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 10 Dec 2023 01:31:35 +0100 Subject: [PATCH 031/257] Scale window size and splitter position by DPI in the sample Make the window less tiny in high DPI under Windows and adjust the initial splitter and drawing coordinates too. --- samples/splitter/splitter.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/samples/splitter/splitter.cpp b/samples/splitter/splitter.cpp index 867e42cb16..e6d73e38a4 100644 --- a/samples/splitter/splitter.cpp +++ b/samples/splitter/splitter.cpp @@ -226,8 +226,7 @@ wxEND_EVENT_TABLE() // My frame constructor MyFrame::MyFrame() - : wxFrame(nullptr, wxID_ANY, "wxSplitterWindow sample", - wxDefaultPosition, wxSize(420, 300)) + : wxFrame(nullptr, wxID_ANY, "wxSplitterWindow sample") { SetIcon(wxICON(sample)); @@ -331,12 +330,14 @@ MyFrame::MyFrame() m_splitter->Initialize(m_left); #else // you can also try -100 - m_splitter->SplitVertically(m_left, m_right, 100); + m_splitter->SplitVertically(m_left, m_right, FromDIP(100)); #endif #if wxUSE_STATUSBAR SetStatusText("Min pane size = 0", 1); #endif // wxUSE_STATUSBAR + + SetInitialSize(FromDIP(wxSize(420, 300))); } MyFrame::~MyFrame() @@ -620,13 +621,13 @@ void MyCanvas::OnDraw(wxDC& dcOrig) wxMirrorDC dc(dcOrig, m_mirror); dc.SetPen(*wxBLACK_PEN); - dc.DrawLine(0, 0, 100, 200); + dc.DrawLine(wxPoint(0, 0), dc.FromDIP(wxPoint(100, 200))); dc.SetBackgroundMode(wxBRUSHSTYLE_TRANSPARENT); - dc.DrawText("Testing", 50, 50); + dc.DrawText("Testing", dc.FromDIP(wxPoint(50, 50))); dc.SetPen(*wxRED_PEN); dc.SetBrush(*wxGREEN_BRUSH); - dc.DrawRectangle(120, 120, 100, 80); + dc.DrawRectangle(dc.FromDIP(wxPoint(120, 120)), dc.FromDIP(wxSize(100, 80))); } From f6a0c7c2912b8a82a30a8d65590d6e8bdeaf90ff Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 10 Dec 2023 17:13:35 +0100 Subject: [PATCH 032/257] Don't scale wxSplitterWindow coordinates by DPI unnecessarily On the platforms with DPI-independent pixels, scaling splitter position and other coordinates by DPI was unnecessary and wrong. Notably this broke wxSplitterWindow under wxGTK since 88a39aa6f8 (Implement wxEVT_DPI_CHANGED generation for wxGTK, 2023-11-06) -- and it had been probably broken under wxOSX even before then. --- src/generic/splitter.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/generic/splitter.cpp b/src/generic/splitter.cpp index 0cd9009cc2..e457f5c6d4 100644 --- a/src/generic/splitter.cpp +++ b/src/generic/splitter.cpp @@ -531,9 +531,14 @@ void wxSplitterWindow::OnSize(wxSizeEvent& event) void wxSplitterWindow::OnDPIChanged(wxDPIChangedEvent& event) { + // On platforms requiring scaling by DPI factor we need to do it whenever + // DPI changes, but elsewhere we shouldn't do it as the same logical + // coordinates are used irrespectively of the current DPI value. +#ifndef wxHAS_DPI_INDEPENDENT_PIXELS m_minimumPaneSize = event.ScaleX(m_minimumPaneSize); m_sashPosition = event.ScaleX(m_sashPosition); m_lastSize = event.Scale(m_lastSize); +#endif // !wxHAS_DPI_INDEPENDENT_PIXELS event.Skip(); } From 0999976f6ddd222b8cfc6959ae1210f82e0723ed Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 01:12:08 +0100 Subject: [PATCH 033/257] Fix using wxImageList in wxTreeCtrl in wxGTK in high DPI The icons positioning was broken by 53b4f4ddf2 (Use physical size in wxImageList, 2023-11-03) because the logical size was calculated incorrectly in the case when wxImageList was used for the icons and ended up being 8x8 for 16x16 icons when using 200% scaling, which was clearly wrong and resulted in the icons not fitting in the space allocated for them because they actually took 32x32 physical pixels due to scaling of all bitmaps from wxImageList. Fix this by correctly taking account of the window DPI scale factor. This is a bit roundabout because using FromPhys() later just undoes this, but it allows to keep using the same code when using wxImageList and wxBitmapBundle for storing bitmaps and so is simpler. Note that we must only do this when wxImageList was provided by the user, i.e. with the legacy code, but not when it was created internally in addition to wxBitmapBundle, as in this case we recreate it on DPI change using the correct, DPI-adjusted size, already, so restrict this scaling to the case when we don't have wxBitmapBundle only. This commit is best viewed ignoring whitespace-only changes. --- include/wx/withimages.h | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/include/wx/withimages.h b/include/wx/withimages.h index bec093d6d0..93744d0288 100644 --- a/include/wx/withimages.h +++ b/include/wx/withimages.h @@ -145,14 +145,32 @@ public: { wxSize size; - // Prefer to use the image list here if we have it because we must have - // already decided for the best size to use when creating it. - // - // Otherwise we need to compute the best size here ourselves. - if ( m_imageList ) - size = m_imageList->GetSize(); - else if ( !m_images.empty() ) - size = wxBitmapBundle::GetConsensusSizeFor(window, m_images); + if ( !m_images.empty() ) + { + // This is a micro-optimization: if we have an image list here, we + // must have created it ourselves, as e.g. wxGenericTreeCtrl does, + // and then we must already have determined the correct size to use + // for the current window DPI and can just return it. + if ( m_imageList ) + { + // Note that we shouldn't scale it by DPI factor here because + // we had already taken it into account when (re)creating it. + size = m_imageList->GetSize(); + } + else + { + // Otherwise we need to compute the best size here ourselves. + size = wxBitmapBundle::GetConsensusSizeFor(window, m_images); + } + } + else if ( m_imageList ) + { + // But if we have just the user-provided image list, we need to + // scale its size by the DPI scale because the bitmaps from it will + // be scaled when they are drawn (they should have scaling factor + // of 1, as for anything else wxBitmapBundle must be used). + size = m_imageList->GetSize() * window->GetDPIScaleFactor(); + } return size; } From 8bf8ae8636fb39c40c3d754628d5fdd47e4e1403 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 01:25:11 +0100 Subject: [PATCH 034/257] Use narrower layout for wxGenericTreeCtrl in all cases Indent and spacing values were reduced back in 618a5e382a (Applied Greg's patch to tree control and related., 2001-08-18) compared to the defaults of 15 and 18 pixels respectively, but only when not using wxTR_NO_LINES style. There doesn't seem to be any good reason to for these values to depend on the style, so use the smaller values always, as they look better and notably don't result in a lot of blank space between the branch toggle icon and the image when using images. --- src/generic/treectlg.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index c86486d0d9..23550d5b80 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -960,8 +960,8 @@ void wxGenericTreeCtrl::Init() m_dirty = false; m_lineHeight = 10; - m_indent = 15; - m_spacing = 18; + m_indent = 10; + m_spacing = 10; m_dragCount = 0; m_isDragging = false; @@ -996,15 +996,6 @@ bool wxGenericTreeCtrl::Create(wxWindow *parent, name ) ) return false; - // If the tree display has no buttons, but does have - // connecting lines, we can use a narrower layout. - // It may not be a good idea to force this... - if (!HasButtons() && !HasFlag(wxTR_NO_LINES)) - { - m_indent= 10; - m_spacing = 10; - } - m_hasExplicitFgCol = m_hasFgCol; m_hasExplicitBgCol = m_hasBgCol; m_hasExplicitFont = m_hasFont; From 17b6b9cd2815650ddf713c3c0364808524d0676b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 01:56:00 +0100 Subject: [PATCH 035/257] Simplify tree line height calculation and improve it in high DPI Remove some code deciding to add 10% of line height between the lines starting from the arbitrary cutoff of 30px, which was there ever since f2593d0dda (Calling a Refresh() before the window is created no longer gives an assert. ..., 1999-12-28) and just add 2 DIPs instead. Also use FromDIP() for the extra space added to GetCharHeight(). --- src/generic/treectlg.cpp | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 23550d5b80..56152ad69d 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -898,10 +898,7 @@ wxGenericTreeItem::DoCalculateSize(wxGenericTreeCtrl* control, int img_h = wxMax(state_h, image_h); m_height = wxMax(img_h, text_h); - if (m_height < 30) - m_height += 2; // at least 2 pixels - else - m_height += m_height / 10; // otherwise 10% extra spacing + m_height += control->FromDIP(2); // See CalculateLineHeight(). if (m_height > control->m_lineHeight) control->m_lineHeight = m_height; @@ -2392,7 +2389,7 @@ void wxGenericTreeCtrl::SortChildren(const wxTreeItemId& itemId) void wxGenericTreeCtrl::CalculateLineHeight() { wxClientDC dc(this); - m_lineHeight = (int)(dc.GetCharHeight() + 4); + m_lineHeight = dc.GetCharHeight() + FromDIP(4); if ( HasImages() ) { @@ -2428,10 +2425,7 @@ void wxGenericTreeCtrl::CalculateLineHeight() } } - if (m_lineHeight < 30) - m_lineHeight += 2; // at least 2 pixels - else - m_lineHeight += m_lineHeight/10; // otherwise 10% extra spacing + m_lineHeight += FromDIP(2); // Add some extra interline space. } void wxGenericTreeCtrl::OnImagesChanged() From a98a1a8bd46299b6aeb469403650f3cee464d694 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 02:01:48 +0100 Subject: [PATCH 036/257] Don't put "if" statements on a single line No real changes, just add line breaks to compound statements for readability. --- src/generic/treectlg.cpp | 59 ++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 56152ad69d..d7e9de71ae 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -297,7 +297,8 @@ public: // set them void SetAttributes(wxItemAttr *attr) { - if ( m_ownsAttr ) delete m_attr; + if ( m_ownsAttr ) + delete m_attr; m_attr = attr; m_ownsAttr = false; m_width = 0; @@ -642,7 +643,8 @@ wxGenericTreeItem::~wxGenericTreeItem() { delete m_data; - if (m_ownsAttr) delete m_attr; + if (m_ownsAttr) + delete m_attr; wxASSERT_MSG( m_children.IsEmpty(), "must call DeleteChildren() before deleting the item" ); @@ -684,9 +686,11 @@ void wxGenericTreeItem::GetSize( int &x, int &y, const wxGenericTreeCtrl *theButton ) { int bottomY=m_y+theButton->GetLineHeight(this); - if ( y < bottomY ) y = bottomY; + if ( y < bottomY ) + y = bottomY; int width = m_x + m_width; - if ( x < width ) x = width; + if ( x < width ) + x = width; if (IsExpanded()) { @@ -781,7 +785,8 @@ wxGenericTreeItem *wxGenericTreeItem::HitTest(const wxPoint& point, } // if children are expanded, fall through to evaluate them - if (m_isCollapsed) return nullptr; + if (m_isCollapsed) + return nullptr; } // evaluate children @@ -824,7 +829,8 @@ int wxGenericTreeItem::GetCurrentImage() const // maybe it doesn't have the specific image we want, // try the default one instead - if ( image == NO_IMAGE ) image = GetImage(); + if ( image == NO_IMAGE ) + image = GetImage(); return image; } @@ -2179,7 +2185,8 @@ void wxGenericTreeCtrl::DoSelectItem(const wxTreeItemId& itemId, // ctrl press if (unselect_others) { - if (is_single) Unselect(); // to speed up thing + if (is_single) + Unselect(); // to speed up thing else UnselectAll(); } @@ -2274,7 +2281,8 @@ void wxGenericTreeCtrl::EnsureVisible(const wxTreeItemId& item) { wxCHECK_RET( item.IsOk(), wxT("invalid tree item") ); - if (!item.IsOk()) return; + if (!item.IsOk()) + return; wxGenericTreeItem *gitem = (wxGenericTreeItem*) item.m_pItem; @@ -2298,8 +2306,6 @@ void wxGenericTreeCtrl::EnsureVisible(const wxTreeItemId& item) } } - //if (parent) CalculatePositions(); - ScrollTo(item); } @@ -2407,7 +2413,8 @@ void wxGenericTreeCtrl::CalculateLineHeight() { int width = 0, height = 0; m_imagesState.GetImageLogicalSize(this, i, width, height); - if (height > m_lineHeight) m_lineHeight = height; + if (height > m_lineHeight) + m_lineHeight = height; } } @@ -2421,7 +2428,8 @@ void wxGenericTreeCtrl::CalculateLineHeight() { int width = 0, height = 0; m_imagesButtons.GetImageLogicalSize(this, i, width, height); - if (height > m_lineHeight) m_lineHeight = height; + if (height > m_lineHeight) + m_lineHeight = height; } } @@ -2895,7 +2903,8 @@ wxGenericTreeCtrl::PaintLevel(wxGenericTreeItem *item, { // draw line down to last child oldY += GetLineHeight(children[n-1])>>1; - if (HasButtons()) y_mid += 5; + if (HasButtons()) + y_mid += 5; // Only draw the portion of the line that is visible, in case // it is huge @@ -3279,7 +3288,8 @@ void wxGenericTreeCtrl::OnChar( wxKeyEvent &event ) while (current.IsOk() && !next) { current = GetItemParent( current ); - if (current) next = GetNextSibling( current ); + if (current) + next = GetNextSibling( current ); } } if (next) @@ -3411,11 +3421,16 @@ wxGenericTreeCtrl::DoTreeHitTest(const wxPoint& point, int& flags) const int w, h; GetSize(&w, &h); flags=0; - if (point.x<0) flags |= wxTREE_HITTEST_TOLEFT; - if (point.x>w) flags |= wxTREE_HITTEST_TORIGHT; - if (point.y<0) flags |= wxTREE_HITTEST_ABOVE; - if (point.y>h) flags |= wxTREE_HITTEST_BELOW; - if (flags) return wxTreeItemId(); + if (point.x<0) + flags |= wxTREE_HITTEST_TOLEFT; + if (point.x>w) + flags |= wxTREE_HITTEST_TORIGHT; + if (point.y<0) + flags |= wxTREE_HITTEST_ABOVE; + if (point.y>h) + flags |= wxTREE_HITTEST_BELOW; + if (flags) + return wxTreeItemId(); if (m_anchor == nullptr) { @@ -3553,7 +3568,8 @@ void wxGenericTreeCtrl::OnRenameTimer() void wxGenericTreeCtrl::OnMouse( wxMouseEvent &event ) { - if ( !m_anchor )return; + if ( !m_anchor ) + return; wxPoint pt = CalcUnscrolledPosition(event.GetPosition()); @@ -3989,7 +4005,8 @@ wxGenericTreeCtrl::CalculateLevel(wxGenericTreeItem *item, void wxGenericTreeCtrl::CalculatePositions() { - if ( !m_anchor ) return; + if ( !m_anchor ) + return; wxClientDC dc(this); PrepareDC( dc ); From 7c7429c015b8ec89a41c36e0fb4342fcea1c1c2f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 02:09:26 +0100 Subject: [PATCH 037/257] Stop using "short" for wxGenericTreeCtrl::m_indent There doesn't seem no reason at all not to use "int" for this member. --- include/wx/generic/treectlg.h | 2 +- src/generic/treectlg.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/wx/generic/treectlg.h b/include/wx/generic/treectlg.h index 7e98c1c1da..22469cf547 100644 --- a/include/wx/generic/treectlg.h +++ b/include/wx/generic/treectlg.h @@ -243,7 +243,7 @@ protected: *m_key_current, // A hint to select a parent item after deleting a child *m_select_me; - unsigned short m_indent; + unsigned int m_indent; int m_lineHeight; wxPen m_dottedPen; wxBrush m_hilightBrush, diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index d7e9de71ae..a55f9a06e6 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -1088,7 +1088,7 @@ unsigned int wxGenericTreeCtrl::GetCount() const void wxGenericTreeCtrl::SetIndent(unsigned int indent) { - m_indent = (unsigned short) indent; + m_indent = indent; m_dirty = true; } @@ -2836,7 +2836,7 @@ wxGenericTreeCtrl::PaintLevel(wxGenericTreeItem *item, { // draw the horizontal line here int x_start = x; - if (x > (signed)m_indent) + if (x > (int)m_indent) x_start -= m_indent; else if (HasFlag(wxTR_LINES_AT_ROOT)) x_start = 3; From 809dabfd430bed93db57987e152c954dd3ab7974 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 02:14:04 +0100 Subject: [PATCH 038/257] Adjust indent and spacing to DPI scaling Move their actual initialization to InitVisualAttributes() where we already have a valid window. --- src/generic/treectlg.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index a55f9a06e6..62dfa103bc 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -963,8 +963,8 @@ void wxGenericTreeCtrl::Init() m_dirty = false; m_lineHeight = 10; - m_indent = 10; - m_spacing = 10; + m_indent = 0; + m_spacing = 0; m_dragCount = 0; m_isDragging = false; @@ -1062,6 +1062,9 @@ void wxGenericTreeCtrl::InitVisualAttributes() m_normalFont = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT); #endif m_boldFont = m_normalFont.Bold(); + + m_indent = FromDIP(10); + m_spacing = FromDIP(10); } // ----------------------------------------------------------------------------- From 60f6c0f4e13e60daee91926c47fa334c4bdfad4f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 02:19:02 +0100 Subject: [PATCH 039/257] Adjust indent and spacing after DPI change if necessary Although wxGenericTreeCtrl is not used under MSW by default, it still doesn't hurt to adjust its metrics when DPI changes there. Note that this shouldn't be done for the platforms using DIPs. --- include/wx/generic/treectlg.h | 2 ++ src/generic/treectlg.cpp | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/include/wx/generic/treectlg.h b/include/wx/generic/treectlg.h index 22469cf547..8475561619 100644 --- a/include/wx/generic/treectlg.h +++ b/include/wx/generic/treectlg.h @@ -357,6 +357,8 @@ protected: virtual wxSize DoGetBestSize() const override; private: + void OnDPIChanged(wxDPIChangedEvent& event); + void OnSysColourChanged(wxSysColourChangedEvent& WXUNUSED(event)) { InitVisualAttributes(); diff --git a/src/generic/treectlg.cpp b/src/generic/treectlg.cpp index 62dfa103bc..02f21c659c 100644 --- a/src/generic/treectlg.cpp +++ b/src/generic/treectlg.cpp @@ -947,6 +947,7 @@ wxBEGIN_EVENT_TABLE(wxGenericTreeCtrl, wxTreeCtrlBase) EVT_KILL_FOCUS (wxGenericTreeCtrl::OnKillFocus) EVT_TREE_ITEM_GETTOOLTIP(wxID_ANY, wxGenericTreeCtrl::OnGetToolTip) EVT_SYS_COLOUR_CHANGED(wxGenericTreeCtrl::OnSysColourChanged) + EVT_DPI_CHANGED(wxGenericTreeCtrl::OnDPIChanged) wxEND_EVENT_TABLE() // ----------------------------------------------------------------------------- @@ -4208,4 +4209,16 @@ wxSize wxGenericTreeCtrl::DoGetBestSize() const return size; } +void wxGenericTreeCtrl::OnDPIChanged(wxDPIChangedEvent& event) +{ + // For the platforms using DPI-dependent pixels we need to adjust various + // metrics after the DPI change. +#ifndef wxHAS_DPI_INDEPENDENT_PIXELS + m_indent = event.ScaleX(m_indent); + m_spacing = event.ScaleX(m_spacing); +#endif // !wxHAS_DPI_INDEPENDENT_PIXELS + + event.Skip(); +} + #endif // wxUSE_TREECTRL From be4c71f74be2a236baa9c1fd8d39d2879d34dadf Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 18:30:09 +0100 Subject: [PATCH 040/257] Default to arm64 + x86_64 universal binaries for wxOSX Using i386 by default isn't useful any more -- but using arm64 is. --- configure | 6 ++---- configure.ac | 8 +++----- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/configure b/configure index 30f90e8582..66a86bbb24 100755 --- a/configure +++ b/configure @@ -22839,10 +22839,8 @@ $as_echo "$as_me: WARNING: --enable-macosx_arch is ignored when --enable-univers if test "x$wxUSE_UNIVERSAL_BINARY" != xyes; then OSX_ARCH_OPTS=$wxUSE_UNIVERSAL_BINARY - else OSX_ARCH_OPTS="i386" - if test "$wxUSE_OSX_COCOA" = 1; then - OSX_ARCH_OPTS="$OSX_ARCH_OPTS,x86_64" - fi + else + OSX_ARCH_OPTS=arm64,x86_64 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for architectures to use in universal binary" >&5 diff --git a/configure.ac b/configure.ac index d8919d3cc9..0d153fd654 100644 --- a/configure.ac +++ b/configure.ac @@ -1160,11 +1160,9 @@ if test "x$wxUSE_UNIVERSAL_BINARY" != xno ; then if test "x$wxUSE_UNIVERSAL_BINARY" != xyes; then OSX_ARCH_OPTS=$wxUSE_UNIVERSAL_BINARY - else dnl Use all architectures supported - OSX_ARCH_OPTS="i386" - if test "$wxUSE_OSX_COCOA" = 1; then - OSX_ARCH_OPTS="$OSX_ARCH_OPTS,x86_64" - fi + else + dnl Default architectures for the universal binaries. + OSX_ARCH_OPTS=arm64,x86_64 fi AC_MSG_CHECKING([for architectures to use in universal binary]) From 209ce24b85764371a237192977a29f335063ffa5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 18:38:22 +0100 Subject: [PATCH 041/257] Recommend using parallel make when building wxWidgets This should help at least some people spend less time waiting. --- docs/gtk/install.md | 19 +++++++++++++++++-- docs/osx/install.md | 14 ++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/docs/gtk/install.md b/docs/gtk/install.md index 4e96a10591..039daa6f25 100644 --- a/docs/gtk/install.md +++ b/docs/gtk/install.md @@ -18,13 +18,28 @@ the following in wxWidgets directory: $ cd buildgtk $ ../configure --with-gtk $ make + +It is recommended to use `-jN` option with the last command, where `N` is a +number of the processors in your system (which can be checked using `nproc` +command if you are not sure), as this will dramatically speed up the build +on modern systems. So in practice you should use a command like this: + + $ make -j16 + +You may also prefer to add `-s` option to avoid normal output from make and/or +redirect it you to a log file for further inspection. + + +If you want to install wxWidgets, please also run + $ sudo make install $ sudo ldconfig (if you get "ldconfig: command not found", try using `/sbin/ldconfig`) -If you don't do the `make install` part, you can still use the libraries from -the `buildgtk` directory, but they may not be available to other users. +but note that this part is optional and you can use the libraries from +the `buildgtk` directory by running `.../buildgtk/wx-config` script using its +full path instead of just using `wx-config`. Note that by default, GTK 3 is used. GTK 2 can be specified with `--with-gtk=2` configure option. diff --git a/docs/osx/install.md b/docs/osx/install.md index 2dfb91a3bf..36d00f2e23 100644 --- a/docs/osx/install.md +++ b/docs/osx/install.md @@ -9,11 +9,11 @@ Most OS X developers should start by downloading and installing Xcode from the App Store. It is a free IDE from Apple that provides all of the tools you need for working with wxWidgets. -After Xcode is installed, download wxWidgets-{version}.tar.bz2 and then +After Xcode is installed, download `wxWidgets-{version}.tar.bz2` and then double-click on it to unpack it to create a wxWidgets directory. Next use Terminal (under Applications, Utilities, Terminal) to access a command -prompt. Use cd to change directories to your wxWidgets directory and execute +prompt. Use `cd` to change directories to your wxWidgets directory and execute the following sets of commands from the wxWidgets directory. mkdir build-cocoa-debug @@ -21,6 +21,16 @@ the following sets of commands from the wxWidgets directory. ../configure --enable-debug make +It is recommended to use `-jN` option with the last command, where `N` is a +number of the processors in your system (which can be checked using `sysctl -n +hw.ncpu` command if you are not sure), as this will dramatically speed up the +build on modern systems. So in practice you should use a command like this: + + make -j16 + +You may also prefer to add `-s` option to avoid normal output from make and/or +redirect it you to a log file for further inspection. + Build the samples and demos cd samples; make;cd .. From 8d8ee12683f97ca5663a27dfd5da4d13674af5f1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 18:43:20 +0100 Subject: [PATCH 042/257] Recommend building just "minimal" sample Don't tell people to build all the samples and demos because this takes time and some of them are badly outdated. Do tell them to build and run the minimal one to check that things work as intended. Also remove links to the wiki from wxOSX instructions, there is not much useful from non-archaeological point of view there. --- docs/gtk/install.md | 9 ++++++++- docs/osx/install.md | 22 +++++++++------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/docs/gtk/install.md b/docs/gtk/install.md index 039daa6f25..bbf57edd31 100644 --- a/docs/gtk/install.md +++ b/docs/gtk/install.md @@ -29,8 +29,15 @@ on modern systems. So in practice you should use a command like this: You may also prefer to add `-s` option to avoid normal output from make and/or redirect it you to a log file for further inspection. +You should build at least the smallest possible wxWidgets sample to verify that +everything is working as intended, by doing -If you want to install wxWidgets, please also run + $ cd samples/minimal + $ make + +and try running it using `./minimal` command from the same directory. + +After confirming that it works, you may want to install wxWidgets by running $ sudo make install $ sudo ldconfig diff --git a/docs/osx/install.md b/docs/osx/install.md index 36d00f2e23..f8a9788cfe 100644 --- a/docs/osx/install.md +++ b/docs/osx/install.md @@ -31,23 +31,19 @@ build on modern systems. So in practice you should use a command like this: You may also prefer to add `-s` option to avoid normal output from make and/or redirect it you to a log file for further inspection. -Build the samples and demos +You should build at least the smallest possible wxWidgets sample to verify that +everything is working as intended, by doing + + cd samples/minimal + make + +and then running `minimal.app` from this directory from Finder. + +If you'd like to, you can also build all the other samples and demos cd samples; make;cd .. cd demos; make;cd .. -After the compilation completes, use Finder to run the samples and demos -* Go to build-cocoa-debug/samples to experiment with the Cocoa samples. -* Go to build-cocoa-debug/demos to experiment with the Cocoa demos. -* Double-click on the executables which have an icon showing three small squares. -* The source code for the samples is in wxWidgets/samples -* The source code for the demos is in wxWidgets/demos - -More information about building on macOS is available in the wxWiki. -Here are two useful links - * https://wiki.wxwidgets.org/Guides_%26_Tutorials - * https://wiki.wxwidgets.org/Development:_wxMac - Advanced topics {#osx_advanced} =============== From 1d9fe9022406f59e825e6d97b8d42708ef9f57c0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 11 Dec 2023 18:49:29 +0100 Subject: [PATCH 043/257] Add section about building release Mac libraries This doesn't seem to be documented anywhere else, but is rather important to know. --- docs/osx/install.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/osx/install.md b/docs/osx/install.md index f8a9788cfe..10143a2dc1 100644 --- a/docs/osx/install.md +++ b/docs/osx/install.md @@ -48,6 +48,24 @@ If you'd like to, you can also build all the other samples and demos Advanced topics {#osx_advanced} =============== +Building library for distribution +--------------------------------- + +When building library for the distribution with your application, you shouldn't +use `--enable-debug` option above but you may want to use `--disable-sys-libs` +option to ensure that it has no dependencies on the other libraries available +on the current system as they might not be present on all systems where the +application is used. + +It is also often desirable to build the final version of the application as +"universal binary", i.e. a combination of binaries for several different +architectures. In this case, you should build wxWidgets as universal binary +too, using `--enable-universal_binary` option. By default, this option enables +building for the usually wanted set of architectures (currently ARM and Intel) +but you may override this by listing the architectures you want to use +explicitly, separating them with commas. + + Installing library {#osx_install} ------------------ From b4d5bce060ed3211a0c6316083677078efbf5c33 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 12 Dec 2023 00:47:14 +0100 Subject: [PATCH 044/257] Make wxSTAY_ON_TOP TLWs transient for parent too in wxGTK Normally such windows should be remain on top of all the other windows, but at least under Wayland they do not, so make them at least remain on top of their parent window -- which should do no harm anyhow and might do some good (by allowing the WM to associate them with the correct window) even if they do stay on top of everything. --- src/gtk/toplevel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gtk/toplevel.cpp b/src/gtk/toplevel.cpp index 590dd7543f..3ebd0cd052 100644 --- a/src/gtk/toplevel.cpp +++ b/src/gtk/toplevel.cpp @@ -737,7 +737,8 @@ bool wxTopLevelWindowGTK::Create( wxWindow *parent, wxWindow *topParent = wxGetTopLevelParent(m_parent); if (topParent && (((GTK_IS_WINDOW(topParent->m_widget)) && (GetExtraStyle() & wxTOPLEVEL_EX_DIALOG)) || - (style & wxFRAME_FLOAT_ON_PARENT))) + (style & wxFRAME_FLOAT_ON_PARENT) || + (style & wxSTAY_ON_TOP))) { gtk_window_set_transient_for( GTK_WINDOW(m_widget), GTK_WINDOW(topParent->m_widget) ); From 149a957f27907c9557c6db982dcc3c5a528ad0c7 Mon Sep 17 00:00:00 2001 From: David Karoly Date: Tue, 12 Dec 2023 19:33:52 +0100 Subject: [PATCH 045/257] Fix wxAnyButton Current/Normal state under wxQt Do not check for hasMouseTracking in QtGetCurrentState as mouse tracking is always enabled in any widget derived from wxQtEventSignalHandler. This resulted in an QtGetCurrentState reporting State_Current when it should have reported State_Normal i.e. the button showed hovering state when it was actually not hovering. After the change, button state will show State_Current only if the mouse pointer is actually hovered on the button. Closes #24129. Closes #24132. --- src/qt/anybutton.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/anybutton.cpp b/src/qt/anybutton.cpp index c1d9e77ce7..f1a819491f 100644 --- a/src/qt/anybutton.cpp +++ b/src/qt/anybutton.cpp @@ -158,7 +158,7 @@ wxAnyButton::State wxAnyButton::QtGetCurrentState() const return State_Pressed; } - if ( HasCapture() || m_qtPushButton->hasMouseTracking() || m_qtPushButton->underMouse() ) + if ( HasCapture() || m_qtPushButton->underMouse() ) { return State_Current; } From 30994678c4f68e2827d0efc380799875b99b0652 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 12 Dec 2023 20:10:40 +0100 Subject: [PATCH 046/257] Reduce the degree of make parallelism in examples And add a warning to not do this if it's not supported. --- docs/gtk/install.md | 5 ++++- docs/osx/install.md | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/gtk/install.md b/docs/gtk/install.md index bbf57edd31..cd30f6813c 100644 --- a/docs/gtk/install.md +++ b/docs/gtk/install.md @@ -24,7 +24,10 @@ number of the processors in your system (which can be checked using `nproc` command if you are not sure), as this will dramatically speed up the build on modern systems. So in practice you should use a command like this: - $ make -j16 + $ make -j8 + +(but don't use it unless you actually have 8 CPUs and enough memory for that +many parallel compiler invocations). You may also prefer to add `-s` option to avoid normal output from make and/or redirect it you to a log file for further inspection. diff --git a/docs/osx/install.md b/docs/osx/install.md index 10143a2dc1..3ffaa899ef 100644 --- a/docs/osx/install.md +++ b/docs/osx/install.md @@ -26,7 +26,10 @@ number of the processors in your system (which can be checked using `sysctl -n hw.ncpu` command if you are not sure), as this will dramatically speed up the build on modern systems. So in practice you should use a command like this: - make -j16 + make -j8 + +(but don't use it unless you actually have 8 CPUs and enough memory for that +many parallel compiler invocations). You may also prefer to add `-s` option to avoid normal output from make and/or redirect it you to a log file for further inspection. From 6d89a14c7256e9d4723f3b212a760ce0152fe7e5 Mon Sep 17 00:00:00 2001 From: Blake-Madden Date: Fri, 8 Dec 2023 06:10:33 -0500 Subject: [PATCH 047/257] Add wxGrid::CopySelection() This code was already used for Ctrl-C handling, refactor it into a separate function that can be called from the application now. This commit is best viewed with --color-moved-ws=ignore-all-space Git option. Closes #24124. --- include/wx/generic/grid.h | 2 + interface/wx/grid.h | 15 +++++ src/generic/grid.cpp | 134 ++++++++++++++++++++------------------ 3 files changed, 87 insertions(+), 64 deletions(-) diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index 72c625e590..047823e56e 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -2284,6 +2284,8 @@ public: void ClearSelection(); + bool CopySelection(); + bool IsInSelection( int row, int col ) const; bool IsInSelection( const wxGridCellCoords& coords ) const diff --git a/interface/wx/grid.h b/interface/wx/grid.h index 2072dc9514..64550f9b4d 100644 --- a/interface/wx/grid.h +++ b/interface/wx/grid.h @@ -4997,6 +4997,21 @@ public: */ void ClearSelection(); + /** + Copies all cells that are currently selected. + + Note that the cells most be contiguously selected; + otherwise, nothing will be copied. + + Returns @c true if content is successfully copied, + @c false otherwise. @c false will be returned if + nothing was selected, the selected cells weren't contiguous, + or a clipboard error occurred. + + @since 3.3.0 + */ + bool CopySelection(); + /** Deselects a row of cells. */ diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 31ca624bbb..c19076c04b 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -6095,72 +6095,12 @@ void wxGrid::OnKeyDown( wxKeyEvent& event ) case 'C': if ( event.GetModifiers() == wxMOD_CONTROL ) { - // Coordinates of the selected block to copy to clipboard. - wxGridBlockCoords sel; - - // Check if we have any selected blocks and if we don't - // have too many of them. - const wxGridBlocks blocks = GetSelectedBlocks(); - wxGridBlocks::iterator iter = blocks.begin(); - if ( iter == blocks.end() ) + if ( !CopySelection() ) { - // No selection, copy just the current cell. - if ( m_currentCellCoords == wxGridNoCellCoords ) - { - // But we don't even have it -- nothing to do then. - event.Skip(); - break; - } - - sel = wxGridBlockCoords(GetGridCursorRow(), - GetGridCursorCol(), - GetGridCursorRow(), - GetGridCursorCol()); + wxLogWarning(_("Error copying grid to the clipboard. " + "Either selected cells were not contiguous or " + "no cell was selected.")); } - else // We do have at least one selected block. - { - sel = *blocks.begin(); - - if ( ++iter != blocks.end() ) - { - // As we use simple text format, we can't copy more - // than one block to clipboard. - wxLogWarning - ( - _("Copying more than one selected block " - "to clipboard is not supported.") - ); - break; - } - } - - wxClipboardLocker lockClipboard; - if ( !lockClipboard ) - { - // Error message should have been already given and we - // don't have much to add. - break; - } - - wxString buf; - for ( int row = sel.GetTopRow(); row <= sel.GetBottomRow(); row++ ) - { - bool first = true; - - for ( int col = sel.GetLeftCol(); col <= sel.GetRightCol(); col++ ) - { - if ( first ) - first = false; - else - buf += '\t'; - - buf += GetCellValue(row, col); - } - - buf += wxTextFile::GetEOL(); - } - - wxTheClipboard->SetData(new wxTextDataObject(buf)); break; } wxFALLTHROUGH; @@ -10852,6 +10792,72 @@ void wxGrid::ClearSelection() m_selection->ClearSelection(); } +bool wxGrid::CopySelection() +{ +#if wxUSE_CLIPBOARD + // Coordinates of the selected block to copy to clipboard. + wxGridBlockCoords sel; + + // Check if we have any selected blocks and if we don't + // have too many of them. + const wxGridBlocks blocks = GetSelectedBlocks(); + wxGridBlocks::iterator iter = blocks.begin(); + if (iter == blocks.end()) + { + // No selection, copy just the current cell. + if (m_currentCellCoords == wxGridNoCellCoords) + { + // But we don't even have it -- nothing to do then. + return false; + } + + sel = wxGridBlockCoords(GetGridCursorRow(), + GetGridCursorCol(), + GetGridCursorRow(), + GetGridCursorCol()); + } + else // We do have at least one selected block. + { + sel = *blocks.begin(); + + if (++iter != blocks.end()) + { + // As we use simple text format, we can't copy more + // than one block to clipboard. + return false; + } + } + + wxClipboardLocker lockClipboard; + if (!lockClipboard) + { + return false; + } + + wxString buf; + for (int row = sel.GetTopRow(); row <= sel.GetBottomRow(); row++) + { + bool first = true; + + for (int col = sel.GetLeftCol(); col <= sel.GetRightCol(); col++) + { + if (first) + first = false; + else + buf += '\t'; + + buf += GetCellValue(row, col); + } + + buf += wxTextFile::GetEOL(); + } + + wxTheClipboard->SetData(new wxTextDataObject(buf)); +#endif // wxUSE_CLIPBOARD + + return true; +} + // This function returns the rectangle that encloses the given block // in device coords clipped to the client size of the grid window. // From cfc5bc6ff2d81da204fcebd8ba8f033cd021faaf Mon Sep 17 00:00:00 2001 From: Bill Su Date: Tue, 12 Dec 2023 20:58:40 -0500 Subject: [PATCH 048/257] more convenient API for wxGenericValidator + wxLB_SINGLE For a single-selection wxListBox, using an int to transfer data to/from wxGenericValidator is more convenient than wxArrayInt. --- interface/wx/valgen.h | 3 +++ src/common/valgen.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/interface/wx/valgen.h b/interface/wx/valgen.h index 40eca58d08..cec4c063b7 100644 --- a/interface/wx/valgen.h +++ b/interface/wx/valgen.h @@ -21,6 +21,9 @@ For example, wxButton and wxTextCtrl transfer data to and from a wxString variable; wxListBox uses a wxArrayInt; wxCheckBox uses a boolean. + @since 3.2.5 + A wxLB_SINGLE wxListBox can also use an int. + For more information, please see @ref overview_validator. @library{wxcore} diff --git a/src/common/valgen.cpp b/src/common/valgen.cpp index 3625f1fc1f..3fa2de301d 100644 --- a/src/common/valgen.cpp +++ b/src/common/valgen.cpp @@ -377,6 +377,17 @@ bool wxGenericValidator::TransferToWindow() return true; } + else if (m_pInt) + { + wxCHECK_MSG( + !(pControl->GetWindowStyle() & (wxLB_MULTIPLE || wxLB_EXTENDED)), + false, + "multi-select control requires wxArrayInt" + ); + pControl->Check(*m_pInt); + + return true; + } else return false; } else @@ -398,6 +409,17 @@ bool wxGenericValidator::TransferToWindow() for ( i = 0 ; i < count; i++ ) pControl->SetSelection(m_pArrayInt->Item(i)); + return true; + } + else if (m_pInt) + { + wxCHECK_MSG( + !(pControl->GetWindowStyle() & (wxLB_MULTIPLE || wxLB_EXTENDED)), + false, + "multi-select control requires wxArrayInt" + ); + pControl->SetSelection(*m_pInt); + return true; } } else @@ -654,6 +676,26 @@ bool wxGenericValidator::TransferFromWindow() return true; } + else if (m_pInt) + { + wxCHECK_MSG( + !(pControl->GetWindowStyle()& (wxLB_MULTIPLE || wxLB_EXTENDED)), + false, + "multi-select control requires wxArrayInt" + ); + + size_t i, + count = pControl->GetCount(); + for ( i = 0; i < count; i++ ) + { + if (pControl->IsChecked(i)) + { + *m_pInt = i; + } + } + + return true; + } else return false; } else @@ -676,6 +718,18 @@ bool wxGenericValidator::TransferFromWindow() m_pArrayInt->Add(i); } + return true; + } + else if (m_pInt) + { + wxCHECK_MSG( + !(pControl->GetWindowStyle() & (wxLB_MULTIPLE || wxLB_EXTENDED)), + false, + "multi-select control requires wxArrayInt" + ); + + *m_pInt = pControl->GetSelection(); + return true; } } else From bdfeb19d19685accc10709a44eaa0c96a6e27a9b Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 13 Dec 2023 18:26:19 -0500 Subject: [PATCH 049/257] HasMultipleSelection() is clearer than handling style bits --- src/common/valgen.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/valgen.cpp b/src/common/valgen.cpp index 3fa2de301d..6724651b48 100644 --- a/src/common/valgen.cpp +++ b/src/common/valgen.cpp @@ -380,7 +380,7 @@ bool wxGenericValidator::TransferToWindow() else if (m_pInt) { wxCHECK_MSG( - !(pControl->GetWindowStyle() & (wxLB_MULTIPLE || wxLB_EXTENDED)), + !pControl->HasMultipleSelection(), false, "multi-select control requires wxArrayInt" ); @@ -414,7 +414,7 @@ bool wxGenericValidator::TransferToWindow() else if (m_pInt) { wxCHECK_MSG( - !(pControl->GetWindowStyle() & (wxLB_MULTIPLE || wxLB_EXTENDED)), + !pControl->HasMultipleSelection(), false, "multi-select control requires wxArrayInt" ); @@ -679,7 +679,7 @@ bool wxGenericValidator::TransferFromWindow() else if (m_pInt) { wxCHECK_MSG( - !(pControl->GetWindowStyle()& (wxLB_MULTIPLE || wxLB_EXTENDED)), + !pControl->HasMultipleSelection(), false, "multi-select control requires wxArrayInt" ); @@ -723,7 +723,7 @@ bool wxGenericValidator::TransferFromWindow() else if (m_pInt) { wxCHECK_MSG( - !(pControl->GetWindowStyle() & (wxLB_MULTIPLE || wxLB_EXTENDED)), + !pControl->HasMultipleSelection(), false, "multi-select control requires wxArrayInt" ); From 8dc3ef4307e2bbe5ad4b9c573d2e998c0bb5fe43 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Wed, 13 Dec 2023 18:31:54 -0500 Subject: [PATCH 050/257] document wxListBox::HasMultipleSelection() as public API --- interface/wx/listbox.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interface/wx/listbox.h b/interface/wx/listbox.h index 19bf3fe0aa..4f96159f00 100644 --- a/interface/wx/listbox.h +++ b/interface/wx/listbox.h @@ -162,6 +162,11 @@ public: const wxString& name = wxListBoxNameStr); ///@} + /** + return true if the listbox allows multiple selection + */ + bool HasMultipleSelection() const + /** Deselects an item in the list box. From de86a70f4ee67043349dbfe9270cf4607c594bad Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 14 Dec 2023 16:29:18 +0100 Subject: [PATCH 051/257] Use symbolic constant for macOS 10.12 version No real changes, just use a constant instead of a hardcoded number in a version check. --- src/osx/cocoa/window.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/osx/cocoa/window.mm b/src/osx/cocoa/window.mm index d8e863bce1..7204c617e3 100644 --- a/src/osx/cocoa/window.mm +++ b/src/osx/cocoa/window.mm @@ -917,7 +917,7 @@ static void SetDrawingEnabledIfFrozenRecursive(wxWidgetCocoaImpl *impl, bool ena [super viewDidMoveToWindow]; } -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 +#if __MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12 - (void) viewWillDraw { if ( WX_IS_MACOS_AVAILABLE(11, 0) ) From ea4800fcb9eb32389bc7d4b93d2819394b5957f0 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 14 Dec 2023 18:58:53 -0500 Subject: [PATCH 052/257] comment that single-select wxListBox allows works with int --- include/wx/valgen.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/wx/valgen.h b/include/wx/valgen.h index 8f26bd1740..c389cbfc81 100644 --- a/include/wx/valgen.h +++ b/include/wx/valgen.h @@ -33,6 +33,7 @@ public: // wxCheckBox, wxRadioButton, wx(Bitmap)ToggleButton wxGenericValidator(bool* val); // wxChoice, wxGauge, wxRadioBox, wxScrollBar, wxSlider, wxSpinButton + // single-selection wxListBox wxGenericValidator(int* val); // wxComboBox, wxTextCtrl, wxButton, wxStaticText (read-only) wxGenericValidator(wxString* val); From 4d3acc90d7c9ea39daf50f937ceff878074fc613 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 14 Dec 2023 19:17:32 -0500 Subject: [PATCH 053/257] wxGenericValidator: add wxColourPickerCtrl support --- include/wx/valgen.h | 4 ++++ interface/wx/valgen.h | 4 ++-- src/common/valgen.cpp | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/include/wx/valgen.h b/include/wx/valgen.h index c389cbfc81..9ce773f3c6 100644 --- a/include/wx/valgen.h +++ b/include/wx/valgen.h @@ -16,6 +16,7 @@ class WXDLLIMPEXP_FWD_BASE wxDateTime; class WXDLLIMPEXP_FWD_BASE wxFileName; +class WXDLLIMPEXP_FWD_CORE wxColour; // ---------------------------------------------------------------------------- // wxGenericValidator performs data transfer between many standard controls and @@ -49,6 +50,8 @@ public: wxGenericValidator(float* val); // wxTextCtrl wxGenericValidator(double* val); + // wxColourPickerCtrl + wxGenericValidator(wxColour* val); wxGenericValidator(const wxGenericValidator& copyFrom); @@ -84,6 +87,7 @@ protected: wxFileName* m_pFileName; float* m_pFloat; double* m_pDouble; + wxColour* m_pColour; private: wxDECLARE_CLASS(wxGenericValidator); diff --git a/interface/wx/valgen.h b/interface/wx/valgen.h index cec4c063b7..6951dc22ac 100644 --- a/interface/wx/valgen.h +++ b/interface/wx/valgen.h @@ -15,14 +15,14 @@ - wxButton, wxRadioButton, wxToggleButton, wxBitmapToggleButton, wxSpinButton - wxCheckBox, wxRadioBox, wxComboBox, wxListBox, wxCheckListBox - wxGauge, wxSlider, wxScrollBar, wxChoice, wxStaticText - - wxSpinCtrl, wxTextCtrl + - wxSpinCtrl, wxTextCtrl, wxColourPickerCtrl It checks the type of the window and uses an appropriate type for it. For example, wxButton and wxTextCtrl transfer data to and from a wxString variable; wxListBox uses a wxArrayInt; wxCheckBox uses a boolean. @since 3.2.5 - A wxLB_SINGLE wxListBox can also use an int. + A wxLB_SINGLE wxListBox can also use an int. wxColourPickerCtrl support. For more information, please see @ref overview_validator. diff --git a/src/common/valgen.cpp b/src/common/valgen.cpp index 6724651b48..0edfd52468 100644 --- a/src/common/valgen.cpp +++ b/src/common/valgen.cpp @@ -41,6 +41,9 @@ #if wxUSE_TOGGLEBTN #include "wx/tglbtn.h" #endif +#if wxUSE_COLOURPICKERCTRL + #include +#endif #include "wx/filename.h" #include "wx/valgen.h" @@ -99,6 +102,12 @@ wxGenericValidator::wxGenericValidator(double *val) m_pDouble = val; } +wxGenericValidator::wxGenericValidator(wxColour* val) +{ + Initialize(); + m_pColour = val; +} + wxGenericValidator::wxGenericValidator(const wxGenericValidator& val) : wxValidator() { @@ -119,6 +128,7 @@ bool wxGenericValidator::Copy(const wxGenericValidator& val) m_pFileName = val.m_pFileName; m_pFloat = val.m_pFloat; m_pDouble = val.m_pDouble; + m_pColour = val.m_pColour; return true; } @@ -424,6 +434,20 @@ bool wxGenericValidator::TransferToWindow() } } else #endif + + // colour controls +#if wxUSE_COLOURPICKERCTRL + if (wxDynamicCast(m_validatorWindow, wxColourPickerCtrl)) + { + wxColourPickerCtrl* pControl = (wxColourPickerCtrl*)m_validatorWindow; + if (m_pColour) + { + pControl->SetColour(*m_pColour); + + return true; + } + } else +#endif { // to match the last 'else' above } @@ -734,6 +758,19 @@ bool wxGenericValidator::TransferFromWindow() } } else #endif +#if wxUSE_COLOURPICKERCTRL + if (wxDynamicCast(m_validatorWindow, wxColourPickerCtrl)) + { + wxColourPickerCtrl* pControl = (wxColourPickerCtrl*)m_validatorWindow; + if (m_pColour) + { + *m_pColour = pControl->GetColour(); + + return true; + } + } + else +#endif // unrecognized control, or bad pointer return false; @@ -756,6 +793,7 @@ void wxGenericValidator::Initialize() m_pFileName = nullptr; m_pFloat = nullptr; m_pDouble = nullptr; + m_pColour = nullptr; } #endif // wxUSE_VALIDATORS From 486b25bd2a19daeec23ba07d38f17346e68bce1e Mon Sep 17 00:00:00 2001 From: Bill Su Date: Thu, 14 Dec 2023 21:26:57 -0500 Subject: [PATCH 054/257] fix #include <> to "" --- src/common/valgen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/valgen.cpp b/src/common/valgen.cpp index 0edfd52468..11a6a6a4ac 100644 --- a/src/common/valgen.cpp +++ b/src/common/valgen.cpp @@ -42,7 +42,7 @@ #include "wx/tglbtn.h" #endif #if wxUSE_COLOURPICKERCTRL - #include + #include "wx/clrpicker.h" #endif #include "wx/filename.h" From fb6a7d5a8ec07e1821c4ba68231405f897000d95 Mon Sep 17 00:00:00 2001 From: Bill Su Date: Sun, 17 Dec 2023 02:10:51 -0500 Subject: [PATCH 055/257] wxGenericValidator: add support for wxCheckBoxState --- include/wx/valgen.h | 3 +++ interface/wx/valgen.h | 1 + src/common/valgen.cpp | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/include/wx/valgen.h b/include/wx/valgen.h index 9ce773f3c6..c3d0faaab8 100644 --- a/include/wx/valgen.h +++ b/include/wx/valgen.h @@ -52,6 +52,8 @@ public: wxGenericValidator(double* val); // wxColourPickerCtrl wxGenericValidator(wxColour* val); + // wxCheckBox + wxGenericValidator(wxCheckBoxState* val); wxGenericValidator(const wxGenericValidator& copyFrom); @@ -88,6 +90,7 @@ protected: float* m_pFloat; double* m_pDouble; wxColour* m_pColour; + wxCheckBoxState* m_pCheckBoxState; private: wxDECLARE_CLASS(wxGenericValidator); diff --git a/interface/wx/valgen.h b/interface/wx/valgen.h index 6951dc22ac..845476022d 100644 --- a/interface/wx/valgen.h +++ b/interface/wx/valgen.h @@ -23,6 +23,7 @@ @since 3.2.5 A wxLB_SINGLE wxListBox can also use an int. wxColourPickerCtrl support. + A 3-state wxCheckBox can use wxCheckBoxState. For more information, please see @ref overview_validator. diff --git a/src/common/valgen.cpp b/src/common/valgen.cpp index 11a6a6a4ac..f73516d27a 100644 --- a/src/common/valgen.cpp +++ b/src/common/valgen.cpp @@ -108,6 +108,12 @@ wxGenericValidator::wxGenericValidator(wxColour* val) m_pColour = val; } +wxGenericValidator::wxGenericValidator(wxCheckBoxState* val) +{ + Initialize(); + m_pCheckBoxState = val; +} + wxGenericValidator::wxGenericValidator(const wxGenericValidator& val) : wxValidator() { @@ -129,6 +135,7 @@ bool wxGenericValidator::Copy(const wxGenericValidator& val) m_pFloat = val.m_pFloat; m_pDouble = val.m_pDouble; m_pColour = val.m_pColour; + m_pCheckBoxState = val.m_pCheckBoxState; return true; } @@ -149,6 +156,11 @@ bool wxGenericValidator::TransferToWindow() pControl->SetValue(*m_pBool); return true; } + else if (m_pCheckBoxState && pControl->Is3State()) + { + pControl->Set3StateValue(*m_pCheckBoxState); + return true; + } } else #endif #if wxUSE_RADIOBTN @@ -471,6 +483,11 @@ bool wxGenericValidator::TransferFromWindow() *m_pBool = pControl->GetValue() ; return true; } + else if (m_pCheckBoxState && pControl->Is3State()) + { + *m_pCheckBoxState = pControl->Get3StateValue(); + return true; + } } else #endif #if wxUSE_RADIOBTN @@ -794,6 +811,7 @@ void wxGenericValidator::Initialize() m_pFloat = nullptr; m_pDouble = nullptr; m_pColour = nullptr; + m_pCheckBoxState = nullptr; } #endif // wxUSE_VALIDATORS From 6afdde58b51e04270b6a865b5674979fcd353707 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sun, 17 Dec 2023 12:29:30 +0100 Subject: [PATCH 056/257] Make wxFloatProperty wxUILocale-aware. wxUILocale settings (especially decimal separator) needs to be taken into account while formatting and validating numbers. Closes #24140. --- src/propgrid/props.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index 3370a1ac61..07a69b842c 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -167,7 +167,7 @@ wxNumericPropertyValidator:: allowedChars += wxS("-+eE"); // Use locale-specific decimal point - allowedChars += wxString::Format(wxS("%g"), 1.1)[1]; + allowedChars.append(wxNumberFormatter::GetDecimalSeparator()); } SetStyle(style); @@ -251,7 +251,7 @@ namespace { // Round value to the required precision. wxVariant variant = value; wxString strVal = prop->ValueToString(variant, wxPG_FULL_VALUE); - strVal.ToDouble(&value); + wxNumberFormatter::FromString(strVal, &value); return value; } } // namespace @@ -955,15 +955,14 @@ wxString wxFloatProperty::ValueToString( wxVariant& value, bool wxFloatProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const { - double value; - if ( text.empty() ) { variant.MakeNull(); return true; } - bool res = text.ToDouble(&value); + double value; + bool res = wxNumberFormatter::FromString(text, &value); if ( res ) { if ( variant != value ) From a8f3e0da7078f756300c07ef0051e3e7d291b931 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sun, 17 Dec 2023 16:05:01 +0100 Subject: [PATCH 057/257] Get rid of of unsupported overloads of wxIntProperty::DoValidation() wxIntProperty::DoValidation() overloads for wxLongLong_t and wxULongLong_t parameters are not supported because for these types there are no direct conversions to wxVariant. Arguments of such types will be handled by overloads for wxLongLong and wxULongLong. --- include/wx/propgrid/props.h | 14 -------------- src/propgrid/props.cpp | 22 ---------------------- 2 files changed, 36 deletions(-) diff --git a/include/wx/propgrid/props.h b/include/wx/propgrid/props.h index 3a4c3f513e..91e6e064ab 100644 --- a/include/wx/propgrid/props.h +++ b/include/wx/propgrid/props.h @@ -215,14 +215,6 @@ private: wxPGValidationInfo* pValidationInfo, int mode = wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ); - -#if defined(wxLongLong_t) - static bool DoValidation( const wxNumericProperty* property, - wxLongLong_t& value, - wxPGValidationInfo* pValidationInfo, - int mode = - wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ); -#endif // wxLongLong_t #endif // wxUSE_LONGLONG static bool DoValidation(const wxNumericProperty* property, long& value, @@ -274,12 +266,6 @@ private: wxULongLong& value, wxPGValidationInfo* pValidationInfo, int mode =wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); -#if defined(wxULongLong_t) - static bool DoValidation(const wxNumericProperty* property, - wxULongLong_t& value, - wxPGValidationInfo* pValidationInfo, - int mode =wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); -#endif // wxULongLong_t #endif // wxUSE_LONGLONG static bool DoValidation(const wxNumericProperty* property, long& value, diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index 07a69b842c..ebe93c82c8 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -470,17 +470,6 @@ bool wxIntProperty::DoValidation( const wxNumericProperty* property, pValidationInfo, mode, wxLongLong(wxPG_LLONG_MIN), wxLongLong(wxPG_LLONG_MAX)); } - -#if defined(wxLongLong_t) -bool wxIntProperty::DoValidation( const wxNumericProperty* property, - wxLongLong_t& value, - wxPGValidationInfo* pValidationInfo, - int mode ) -{ - return property->DoNumericValidation(value, pValidationInfo, - mode, wxPG_LLONG_MIN, wxPG_LLONG_MAX); -} -#endif // wxLongLong_t #endif // wxUSE_LONGLONG bool wxIntProperty::DoValidation(const wxNumericProperty* property, @@ -743,17 +732,6 @@ bool wxUIntProperty::DoValidation(const wxNumericProperty* property, return property->DoNumericValidation(value, pValidationInfo, mode, wxULongLong(0), wxULongLong(wxPG_ULLONG_MAX)); } - -#if defined(wxULongLong_t) -bool wxUIntProperty::DoValidation(const wxNumericProperty* property, - wxULongLong_t& value, - wxPGValidationInfo* pValidationInfo, - int mode ) -{ - return property->DoNumericValidation(value, pValidationInfo, - mode, 0, wxPG_ULLONG_MAX); -} -#endif // wxULongLong_t #endif // wxUSE_LONGLONG bool wxUIntProperty::DoValidation(const wxNumericProperty* property, From 63805074df75aa2c28d9cfec13689debc3cdecce Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sun, 17 Dec 2023 16:06:37 +0100 Subject: [PATCH 058/257] Use standard library function to swap items in the array --- src/propgrid/props.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index ebe93c82c8..1ac680d1d6 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -29,6 +29,7 @@ #include "wx/propgrid/private.h" #include +#include constexpr double wxPG_DBL_MIN = std::numeric_limits::min(); constexpr double wxPG_DBL_MAX = std::numeric_limits::max(); @@ -2509,7 +2510,7 @@ void wxPGArrayStringEditorDialog::ArrayRemoveAt( int index ) void wxPGArrayStringEditorDialog::ArraySwap( size_t first, size_t second ) { - wxSwap(m_array[first], m_array[second]); + std::swap(m_array[first], m_array[second]); } wxPGArrayStringEditorDialog::wxPGArrayStringEditorDialog() From d95074e48d1bbf3aeb6b01e7d910e7af2d97a5c4 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sun, 17 Dec 2023 16:11:34 +0100 Subject: [PATCH 059/257] Use dedicated function to get value from wxPGChoicesData --- src/propgrid/property.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/propgrid/property.cpp b/src/propgrid/property.cpp index d09c7fe7f8..ab5c58fabd 100644 --- a/src/propgrid/property.cpp +++ b/src/propgrid/property.cpp @@ -3086,8 +3086,7 @@ int wxPGChoices::Index( int val ) const { for ( unsigned int i = 0; i < m_data->GetCount(); i++ ) { - const wxPGChoiceEntry& entry = m_data->Item(i); - if ( entry.GetValue() == val ) + if ( GetValue(i) == val ) return i; } } From 74bacb097f0072997b8f4c25b31b5e80fc01bd71 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sun, 17 Dec 2023 16:12:08 +0100 Subject: [PATCH 060/257] Guard function with wxCHECK rather than wxASSERT --- src/propgrid/property.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/propgrid/property.cpp b/src/propgrid/property.cpp index ab5c58fabd..d7cc69f623 100644 --- a/src/propgrid/property.cpp +++ b/src/propgrid/property.cpp @@ -2220,7 +2220,7 @@ bool wxPGProperty::HasVisibleChildren() const bool wxPGProperty::RecreateEditor() { wxPropertyGrid* pg = GetGrid(); - wxASSERT(pg); + wxCHECK_MSG(pg, false, "Cannot recreate editor for detached property"); wxPGProperty* selected = pg->GetSelection(); if ( this == selected ) From 41109f64f0c7a112628f679b3755e71b49a890c3 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sun, 17 Dec 2023 16:12:22 +0100 Subject: [PATCH 061/257] Initialize member variables --- include/wx/propgrid/property.h | 4 ++-- src/propgrid/editors.cpp | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/wx/propgrid/property.h b/include/wx/propgrid/property.h index 935c81d2e1..5cfd6f7118 100644 --- a/include/wx/propgrid/property.h +++ b/include/wx/propgrid/property.h @@ -729,10 +729,10 @@ public: // Simple interface constructor. wxPGChoices( wxPGChoicesData* data ) + : m_data(data) { wxCHECK_RET(data, "Data pointer cannot be null"); - m_data = data; - data->IncRef(); + m_data->IncRef(); } // Destructor. diff --git a/src/propgrid/editors.cpp b/src/propgrid/editors.cpp index 0b434cb536..b7ba31714e 100644 --- a/src/propgrid/editors.cpp +++ b/src/propgrid/editors.cpp @@ -564,6 +564,7 @@ public: wxPGComboBox() : wxOwnerDrawnComboBox() , m_dclickProcessor(nullptr) + , m_selProp(nullptr) { } From 0a1042292df978ca7179fbe77028dca9c0003a18 Mon Sep 17 00:00:00 2001 From: Blake-Madden Date: Fri, 15 Dec 2023 06:28:43 -0500 Subject: [PATCH 062/257] Don't add new line when copying only one wxGrid cell to clipboard Append the new line character only before starting the next line instead of doing it after each line to avoid having it when there is just one line, as this as unexpected when copying a single cell. Closes #24139. --- src/generic/grid.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index c19076c04b..36bd8dbdc8 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -10834,22 +10834,26 @@ bool wxGrid::CopySelection() return false; } + bool firstRow = true; wxString buf; for (int row = sel.GetTopRow(); row <= sel.GetBottomRow(); row++) { - bool first = true; + if (firstRow) + firstRow = false; + else + buf += wxTextFile::GetEOL(); + + bool firstColumn = true; for (int col = sel.GetLeftCol(); col <= sel.GetRightCol(); col++) { - if (first) - first = false; + if (firstColumn) + firstColumn = false; else buf += '\t'; buf += GetCellValue(row, col); } - - buf += wxTextFile::GetEOL(); } wxTheClipboard->SetData(new wxTextDataObject(buf)); From eabaec546ba0441d0bbc8053c264ea1e47ee89de Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 18 Dec 2023 15:06:33 +0100 Subject: [PATCH 063/257] Restore "wxSuffix" MSBuild macro for compatibility Restore the macro removed in 0d6f2f2b85 (Remove wxSuffix from MSBuild files, it's always "u" now, 2022-10-28) as it can still be used in the user projects importing wx properties files and it doesn't cost anything to keep it. --- build/msw/wx_setup.props | 1 + 1 file changed, 1 insertion(+) diff --git a/build/msw/wx_setup.props b/build/msw/wx_setup.props index c02178f5f1..8aac1ee695 100644 --- a/build/msw/wx_setup.props +++ b/build/msw/wx_setup.props @@ -11,6 +11,7 @@ vc + u custom dynamic MultiThreadedDLL From f8a6f0cd39c55aeeb5ed293eb9be47a80dfe9102 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 18 Dec 2023 16:49:35 +0100 Subject: [PATCH 064/257] Initialize wxFileDialog::m_data in default ctor in wxMSW too This corrects a problem introduced in 11ed91af8f (Add missing default constructor of wxFileDialog in wxMSW, 2023-12-03) as m_data remained uninitialized when default ctor was used. See #24113. --- include/wx/msw/filedlg.h | 2 +- src/msw/filedlg.cpp | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/wx/msw/filedlg.h b/include/wx/msw/filedlg.h index 090c3e2418..7c97723dd7 100644 --- a/include/wx/msw/filedlg.h +++ b/include/wx/msw/filedlg.h @@ -79,7 +79,7 @@ private: // Extra data, possibly null if not needed, use MSWData() to access it if // it should be created on demand. - wxFileDialogMSWData* m_data; + wxFileDialogMSWData* m_data = nullptr; wxDECLARE_DYNAMIC_CLASS(wxFileDialog); diff --git a/src/msw/filedlg.cpp b/src/msw/filedlg.cpp index f685688a63..75a0b46012 100644 --- a/src/msw/filedlg.cpp +++ b/src/msw/filedlg.cpp @@ -1024,8 +1024,6 @@ wxFileDialog::wxFileDialog(wxWindow *parent, { // NB: all style checks are done by wxFileDialogBase::Create - m_data = nullptr; - // Must set to zero, otherwise the wx routines won't size the window // the second time you call the file dialog, because it thinks it is // already at the requested size.. (when centering) From 50325bd2cd87109a20378948a05961100d86ec00 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 18 Dec 2023 16:51:58 +0100 Subject: [PATCH 065/257] Reset stored position in wxMSW wxFileDialog dtor, not ctor As there is more then one ctor since 11ed91af8f (Add missing default constructor of wxFileDialog in wxMSW, 2023-12-03), this code would need to be duplicated in the default ctor too now, but it seems simpler and more logical to move it to the dtor instead. See #24113. --- src/msw/filedlg.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/msw/filedlg.cpp b/src/msw/filedlg.cpp index 75a0b46012..ffd83aa7ba 100644 --- a/src/msw/filedlg.cpp +++ b/src/msw/filedlg.cpp @@ -1023,6 +1023,11 @@ wxFileDialog::wxFileDialog(wxWindow *parent, { // NB: all style checks are done by wxFileDialogBase::Create +} + +wxFileDialog::~wxFileDialog() +{ + delete m_data; // Must set to zero, otherwise the wx routines won't size the window // the second time you call the file dialog, because it thinks it is @@ -1031,11 +1036,6 @@ wxFileDialog::wxFileDialog(wxWindow *parent, gs_rectDialog.y = 0; } -wxFileDialog::~wxFileDialog() -{ - delete m_data; -} - wxFileDialogMSWData& wxFileDialog::MSWData() { if ( !m_data ) From ff68b61b84f185b0975f43e1098b97e69f613c08 Mon Sep 17 00:00:00 2001 From: Bill Su <69879726+wsu-cb@users.noreply.github.com> Date: Mon, 18 Dec 2023 11:43:28 -0500 Subject: [PATCH 066/257] Update interface/wx/valgen.h Co-authored-by: VZ --- interface/wx/valgen.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/wx/valgen.h b/interface/wx/valgen.h index 845476022d..3dc150713b 100644 --- a/interface/wx/valgen.h +++ b/interface/wx/valgen.h @@ -15,7 +15,7 @@ - wxButton, wxRadioButton, wxToggleButton, wxBitmapToggleButton, wxSpinButton - wxCheckBox, wxRadioBox, wxComboBox, wxListBox, wxCheckListBox - wxGauge, wxSlider, wxScrollBar, wxChoice, wxStaticText - - wxSpinCtrl, wxTextCtrl, wxColourPickerCtrl + - wxSpinCtrl, wxTextCtrl, wxColourPickerCtrl (since wxWidgets 3.3.0 or later). It checks the type of the window and uses an appropriate type for it. For example, wxButton and wxTextCtrl transfer data to and from a From 0a743cdf12658aa7a4b7a1667ef99559603086fc Mon Sep 17 00:00:00 2001 From: Blake-Madden <66873089+Blake-Madden@users.noreply.github.com> Date: Sun, 17 Dec 2023 06:44:34 -0500 Subject: [PATCH 067/257] Don't free a locked HGLOBAL in wxMSW printing code This resulted in at least a use-after-free ASAN warning and possibly actual memory corruption, so ensure that we unlock m_devMode before freeing and resetting it. Closes #24146. Co-authored-by: Vadim Zeitlin --- src/msw/printdlg.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/msw/printdlg.cpp b/src/msw/printdlg.cpp index 4a1f8a6994..21d7681529 100644 --- a/src/msw/printdlg.cpp +++ b/src/msw/printdlg.cpp @@ -520,6 +520,7 @@ void wxWindowsPrintNativeData::InitializeDevMode(const wxString& printerName, Wi } // Try to initialize devmode to user or system default. + GlobalPtr newDevMode; if (m_devMode) { GlobalPtrLock lockDevMode(m_devMode); @@ -548,18 +549,21 @@ void wxWindowsPrintNativeData::InitializeDevMode(const wxString& printerName, Wi if ( pDevMode ) { DWORD devModeSize = pDevMode->dmSize + pDevMode->dmDriverExtra; - GlobalPtr newDevMode(devModeSize, GMEM_FIXED | GMEM_ZEROINIT); + newDevMode.Init(devModeSize, GMEM_FIXED | GMEM_ZEROINIT); if ( newDevMode ) { memcpy(newDevMode, pDevMode, devModeSize); - - ::GlobalFree(m_devMode); - m_devMode = newDevMode.Release(); } } } } } + + if ( newDevMode ) + { + ::GlobalFree(static_cast(m_devMode)); + m_devMode = newDevMode.Release(); + } } bool wxWindowsPrintNativeData::TransferFrom( const wxPrintData &data ) From ca405352e0507a8020555f5d3064082dadc80211 Mon Sep 17 00:00:00 2001 From: Viachaslau Lisouski Date: Fri, 15 Dec 2023 09:07:39 +0100 Subject: [PATCH 068/257] Add wxFileSystemHandler for "data" scheme This notably allows embedding images directly in HTML. Closes #24138. --- Makefile.in | 19 +++++ build/bakefiles/files.bkl | 2 + build/cmake/files.cmake | 2 + build/files | 2 + build/msw/makefile.gcc | 16 ++++ build/msw/makefile.vc | 16 ++++ build/msw/wx_base.vcxproj | 2 + build/msw/wx_base.vcxproj.filters | 6 ++ docs/doxygen/overviews/filesystem.h | 4 + include/wx/fs_data.h | 31 +++++++ interface/wx/fs_data.h | 31 +++++++ src/common/fs_data.cpp | 126 ++++++++++++++++++++++++++++ tests/allheaders.h | 1 + tests/filesys/filesystest.cpp | 49 ++++++++++- 14 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 include/wx/fs_data.h create mode 100644 interface/wx/fs_data.h create mode 100644 src/common/fs_data.cpp diff --git a/Makefile.in b/Makefile.in index b3ec7f4260..67bdae4306 100644 --- a/Makefile.in +++ b/Makefile.in @@ -603,6 +603,7 @@ ALL_BASE_HEADERS = \ wx/lzmastream.h \ wx/localedefs.h \ wx/uilocale.h \ + wx/fs_data.h \ $(BASE_PLATFORM_HDR) \ wx/fs_inet.h \ wx/protocol/file.h \ @@ -789,6 +790,7 @@ ALL_PORTS_BASE_HEADERS = \ wx/lzmastream.h \ wx/localedefs.h \ wx/uilocale.h \ + wx/fs_data.h \ wx/unix/app.h \ wx/unix/apptbase.h \ wx/unix/apptrait.h \ @@ -925,6 +927,7 @@ ALL_BASE_SOURCES = \ src/common/secretstore.cpp \ src/common/lzmastream.cpp \ src/common/uilocale.cpp \ + src/common/fs_data.cpp \ src/common/fdiodispatcher.cpp \ src/common/selectdispatcher.cpp \ src/unix/appunix.cpp \ @@ -1130,6 +1133,7 @@ MONODLL_OBJECTS = \ monodll_common_secretstore.o \ monodll_lzmastream.o \ monodll_common_uilocale.o \ + monodll_fs_data.o \ $(__BASE_PLATFORM_SRC_OBJECTS) \ monodll_event.o \ monodll_fs_mem.o \ @@ -1289,6 +1293,7 @@ MONOLIB_OBJECTS = \ monolib_common_secretstore.o \ monolib_lzmastream.o \ monolib_common_uilocale.o \ + monolib_fs_data.o \ $(__BASE_PLATFORM_SRC_OBJECTS_1) \ monolib_event.o \ monolib_fs_mem.o \ @@ -1417,6 +1422,7 @@ BASEDLL_OBJECTS = \ basedll_common_secretstore.o \ basedll_lzmastream.o \ basedll_common_uilocale.o \ + basedll_fs_data.o \ $(__BASE_PLATFORM_SRC_OBJECTS_2) \ basedll_event.o \ basedll_fs_mem.o \ @@ -1527,6 +1533,7 @@ BASELIB_OBJECTS = \ baselib_common_secretstore.o \ baselib_lzmastream.o \ baselib_common_uilocale.o \ + baselib_fs_data.o \ $(__BASE_PLATFORM_SRC_OBJECTS_3) \ baselib_event.o \ baselib_fs_mem.o \ @@ -14966,6 +14973,9 @@ monodll_lzmastream.o: $(srcdir)/src/common/lzmastream.cpp $(MONODLL_ODEP) monodll_common_uilocale.o: $(srcdir)/src/common/uilocale.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/uilocale.cpp +monodll_fs_data.o: $(srcdir)/src/common/fs_data.cpp $(MONODLL_ODEP) + $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/common/fs_data.cpp + monodll_unix_mimetype.o: $(srcdir)/src/unix/mimetype.cpp $(MONODLL_ODEP) $(CXXC) -c -o $@ $(MONODLL_CXXFLAGS) $(srcdir)/src/unix/mimetype.cpp @@ -19712,6 +19722,9 @@ monolib_lzmastream.o: $(srcdir)/src/common/lzmastream.cpp $(MONOLIB_ODEP) monolib_common_uilocale.o: $(srcdir)/src/common/uilocale.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/uilocale.cpp +monolib_fs_data.o: $(srcdir)/src/common/fs_data.cpp $(MONOLIB_ODEP) + $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/common/fs_data.cpp + monolib_unix_mimetype.o: $(srcdir)/src/unix/mimetype.cpp $(MONOLIB_ODEP) $(CXXC) -c -o $@ $(MONOLIB_CXXFLAGS) $(srcdir)/src/unix/mimetype.cpp @@ -24458,6 +24471,9 @@ basedll_lzmastream.o: $(srcdir)/src/common/lzmastream.cpp $(BASEDLL_ODEP) basedll_common_uilocale.o: $(srcdir)/src/common/uilocale.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/common/uilocale.cpp +basedll_fs_data.o: $(srcdir)/src/common/fs_data.cpp $(BASEDLL_ODEP) + $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/common/fs_data.cpp + basedll_unix_mimetype.o: $(srcdir)/src/unix/mimetype.cpp $(BASEDLL_ODEP) $(CXXC) -c -o $@ $(BASEDLL_CXXFLAGS) $(srcdir)/src/unix/mimetype.cpp @@ -24938,6 +24954,9 @@ baselib_lzmastream.o: $(srcdir)/src/common/lzmastream.cpp $(BASELIB_ODEP) baselib_common_uilocale.o: $(srcdir)/src/common/uilocale.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/common/uilocale.cpp +baselib_fs_data.o: $(srcdir)/src/common/fs_data.cpp $(BASELIB_ODEP) + $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/common/fs_data.cpp + baselib_unix_mimetype.o: $(srcdir)/src/unix/mimetype.cpp $(BASELIB_ODEP) $(CXXC) -c -o $@ $(BASELIB_CXXFLAGS) $(srcdir)/src/unix/mimetype.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index ec7c3637fc..ba64fd032a 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -580,6 +580,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! src/common/secretstore.cpp src/common/lzmastream.cpp src/common/uilocale.cpp + src/common/fs_data.cpp src/common/event.cpp @@ -755,6 +756,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/lzmastream.h wx/localedefs.h wx/uilocale.h + wx/fs_data.h diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index d04334668e..691d5e744e 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -492,6 +492,7 @@ set(BASE_CMN_SRC src/generic/fswatcherg.cpp src/common/lzmastream.cpp src/common/uilocale.cpp + src/common/fs_data.cpp ) set(BASE_AND_GUI_CMN_SRC @@ -669,6 +670,7 @@ set(BASE_CMN_HDR wx/lzmastream.h wx/localedefs.h wx/uilocale.h + wx/fs_data.h ) set(NET_UNIX_SRC diff --git a/build/files b/build/files index a25c420544..730b5c8124 100644 --- a/build/files +++ b/build/files @@ -455,6 +455,7 @@ BASE_CMN_SRC = src/common/filtfind.cpp src/common/fmapbase.cpp src/common/fs_arc.cpp + src/common/fs_data.cpp src/common/fs_filter.cpp src/common/hash.cpp src/common/hashmap.cpp @@ -571,6 +572,7 @@ BASE_CMN_HDR = wx/fontenc.h wx/fontmap.h wx/fs_arc.h + wx/fs_data.h wx/fs_filter.h wx/fs_mem.h wx/fs_zip.h diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 80cb9d684d..1c91477dc5 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -498,6 +498,7 @@ MONODLL_OBJECTS = \ $(OBJS)\monodll_common_secretstore.o \ $(OBJS)\monodll_lzmastream.o \ $(OBJS)\monodll_common_uilocale.o \ + $(OBJS)\monodll_fs_data.o \ $(OBJS)\monodll_basemsw.o \ $(OBJS)\monodll_crashrpt.o \ $(OBJS)\monodll_debughlp.o \ @@ -659,6 +660,7 @@ MONOLIB_OBJECTS = \ $(OBJS)\monolib_common_secretstore.o \ $(OBJS)\monolib_lzmastream.o \ $(OBJS)\monolib_common_uilocale.o \ + $(OBJS)\monolib_fs_data.o \ $(OBJS)\monolib_basemsw.o \ $(OBJS)\monolib_crashrpt.o \ $(OBJS)\monolib_debughlp.o \ @@ -808,6 +810,7 @@ BASEDLL_OBJECTS = \ $(OBJS)\basedll_common_secretstore.o \ $(OBJS)\basedll_lzmastream.o \ $(OBJS)\basedll_common_uilocale.o \ + $(OBJS)\basedll_fs_data.o \ $(OBJS)\basedll_basemsw.o \ $(OBJS)\basedll_crashrpt.o \ $(OBJS)\basedll_debughlp.o \ @@ -938,6 +941,7 @@ BASELIB_OBJECTS = \ $(OBJS)\baselib_common_secretstore.o \ $(OBJS)\baselib_lzmastream.o \ $(OBJS)\baselib_common_uilocale.o \ + $(OBJS)\baselib_fs_data.o \ $(OBJS)\baselib_basemsw.o \ $(OBJS)\baselib_crashrpt.o \ $(OBJS)\baselib_debughlp.o \ @@ -7235,6 +7239,9 @@ $(OBJS)\monodll_lzmastream.o: ../../src/common/lzmastream.cpp $(OBJS)\monodll_common_uilocale.o: ../../src/common/uilocale.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monodll_fs_data.o: ../../src/common/fs_data.cpp + $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monodll_basemsw.o: ../../src/msw/basemsw.cpp $(CXX) -c -o $@ $(MONODLL_CXXFLAGS) $(CPPDEPS) $< @@ -9826,6 +9833,9 @@ $(OBJS)\monolib_lzmastream.o: ../../src/common/lzmastream.cpp $(OBJS)\monolib_common_uilocale.o: ../../src/common/uilocale.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\monolib_fs_data.o: ../../src/common/fs_data.cpp + $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\monolib_basemsw.o: ../../src/msw/basemsw.cpp $(CXX) -c -o $@ $(MONOLIB_CXXFLAGS) $(CPPDEPS) $< @@ -12417,6 +12427,9 @@ $(OBJS)\basedll_lzmastream.o: ../../src/common/lzmastream.cpp $(OBJS)\basedll_common_uilocale.o: ../../src/common/uilocale.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\basedll_fs_data.o: ../../src/common/fs_data.cpp + $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\basedll_basemsw.o: ../../src/msw/basemsw.cpp $(CXX) -c -o $@ $(BASEDLL_CXXFLAGS) $(CPPDEPS) $< @@ -12759,6 +12772,9 @@ $(OBJS)\baselib_lzmastream.o: ../../src/common/lzmastream.cpp $(OBJS)\baselib_common_uilocale.o: ../../src/common/uilocale.cpp $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< +$(OBJS)\baselib_fs_data.o: ../../src/common/fs_data.cpp + $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< + $(OBJS)\baselib_basemsw.o: ../../src/msw/basemsw.cpp $(CXX) -c -o $@ $(BASELIB_CXXFLAGS) $(CPPDEPS) $< diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index a86e81109b..8bb1f4ebf5 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -534,6 +534,7 @@ MONODLL_OBJECTS = \ $(OBJS)\monodll_common_secretstore.obj \ $(OBJS)\monodll_lzmastream.obj \ $(OBJS)\monodll_common_uilocale.obj \ + $(OBJS)\monodll_fs_data.obj \ $(OBJS)\monodll_basemsw.obj \ $(OBJS)\monodll_crashrpt.obj \ $(OBJS)\monodll_debughlp.obj \ @@ -704,6 +705,7 @@ MONOLIB_OBJECTS = \ $(OBJS)\monolib_common_secretstore.obj \ $(OBJS)\monolib_lzmastream.obj \ $(OBJS)\monolib_common_uilocale.obj \ + $(OBJS)\monolib_fs_data.obj \ $(OBJS)\monolib_basemsw.obj \ $(OBJS)\monolib_crashrpt.obj \ $(OBJS)\monolib_debughlp.obj \ @@ -862,6 +864,7 @@ BASEDLL_OBJECTS = \ $(OBJS)\basedll_common_secretstore.obj \ $(OBJS)\basedll_lzmastream.obj \ $(OBJS)\basedll_common_uilocale.obj \ + $(OBJS)\basedll_fs_data.obj \ $(OBJS)\basedll_basemsw.obj \ $(OBJS)\basedll_crashrpt.obj \ $(OBJS)\basedll_debughlp.obj \ @@ -1002,6 +1005,7 @@ BASELIB_OBJECTS = \ $(OBJS)\baselib_common_secretstore.obj \ $(OBJS)\baselib_lzmastream.obj \ $(OBJS)\baselib_common_uilocale.obj \ + $(OBJS)\baselib_fs_data.obj \ $(OBJS)\baselib_basemsw.obj \ $(OBJS)\baselib_crashrpt.obj \ $(OBJS)\baselib_debughlp.obj \ @@ -7692,6 +7696,9 @@ $(OBJS)\monodll_lzmastream.obj: ..\..\src\common\lzmastream.cpp $(OBJS)\monodll_common_uilocale.obj: ..\..\src\common\uilocale.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\uilocale.cpp +$(OBJS)\monodll_fs_data.obj: ..\..\src\common\fs_data.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\common\fs_data.cpp + $(OBJS)\monodll_basemsw.obj: ..\..\src\msw\basemsw.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONODLL_CXXFLAGS) ..\..\src\msw\basemsw.cpp @@ -10283,6 +10290,9 @@ $(OBJS)\monolib_lzmastream.obj: ..\..\src\common\lzmastream.cpp $(OBJS)\monolib_common_uilocale.obj: ..\..\src\common\uilocale.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\uilocale.cpp +$(OBJS)\monolib_fs_data.obj: ..\..\src\common\fs_data.cpp + $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\common\fs_data.cpp + $(OBJS)\monolib_basemsw.obj: ..\..\src\msw\basemsw.cpp $(CXX) /c /nologo /TP /Fo$@ $(MONOLIB_CXXFLAGS) ..\..\src\msw\basemsw.cpp @@ -12874,6 +12884,9 @@ $(OBJS)\basedll_lzmastream.obj: ..\..\src\common\lzmastream.cpp $(OBJS)\basedll_common_uilocale.obj: ..\..\src\common\uilocale.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\uilocale.cpp +$(OBJS)\basedll_fs_data.obj: ..\..\src\common\fs_data.cpp + $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\common\fs_data.cpp + $(OBJS)\basedll_basemsw.obj: ..\..\src\msw\basemsw.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASEDLL_CXXFLAGS) ..\..\src\msw\basemsw.cpp @@ -13216,6 +13229,9 @@ $(OBJS)\baselib_lzmastream.obj: ..\..\src\common\lzmastream.cpp $(OBJS)\baselib_common_uilocale.obj: ..\..\src\common\uilocale.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\common\uilocale.cpp +$(OBJS)\baselib_fs_data.obj: ..\..\src\common\fs_data.cpp + $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\common\fs_data.cpp + $(OBJS)\baselib_basemsw.obj: ..\..\src\msw\basemsw.cpp $(CXX) /c /nologo /TP /Fo$@ $(BASELIB_CXXFLAGS) ..\..\src\msw\basemsw.cpp diff --git a/build/msw/wx_base.vcxproj b/build/msw/wx_base.vcxproj index f7ae103688..ec67b604be 100644 --- a/build/msw/wx_base.vcxproj +++ b/build/msw/wx_base.vcxproj @@ -622,6 +622,7 @@ $(IntDir)common_%(Filename).obj $(IntDir)common_%(Filename).obj + @@ -841,6 +842,7 @@ + diff --git a/build/msw/wx_base.vcxproj.filters b/build/msw/wx_base.vcxproj.filters index fc5b55840e..f0068f6427 100644 --- a/build/msw/wx_base.vcxproj.filters +++ b/build/msw/wx_base.vcxproj.filters @@ -123,6 +123,9 @@ Common Sources + + Common Sources + Common Sources @@ -535,6 +538,9 @@ Common Headers + + Common Headers + Common Headers diff --git a/docs/doxygen/overviews/filesystem.h b/docs/doxygen/overviews/filesystem.h index 5a83c97413..ea0cd30c93 100644 --- a/docs/doxygen/overviews/filesystem.h +++ b/docs/doxygen/overviews/filesystem.h @@ -73,6 +73,10 @@ The following virtual file system handlers are part of wxWidgets so far: A handler for archives such as zip and tar. Include file is wx/fs_arc.h. URLs examples: "archive.zip#zip:filename", "archive.tar.gz#gzip:#tar:filename". +@li @b wxDataSchemeFSHandler: + A handler for accessing data inlined in URI according to RFC 2397. + URI example: "data:text/plain;base64,d3hXaWRnZXRzIGV4YW1wbGU=". + Include file is wx/fs_data.h. @li @b wxFilterFSHandler: A handler for compression schemes such as gzip. Header is wx/fs_filter.h. URLs are in the form, e.g.: diff --git a/include/wx/fs_data.h b/include/wx/fs_data.h new file mode 100644 index 0000000000..eea524a425 --- /dev/null +++ b/include/wx/fs_data.h @@ -0,0 +1,31 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/fs_data.h +// Purpose: DATA scheme file system. +// Author: Vyacheslav Lisovski +// Copyright: (c) 2023 Vyacheslav Lisovski +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_FS_DATA_H_ +#define _WX_FS_DATA_H_ + +#include "wx/defs.h" + +#if wxUSE_FILESYSTEM + +#include "wx/filesys.h" + +// ---------------------------------------------------------------------------- +// wxDataSchemeFSHandler +// ---------------------------------------------------------------------------- + +class WXDLLIMPEXP_BASE wxDataSchemeFSHandler : public wxFileSystemHandler +{ +public: + virtual bool CanOpen(const wxString& location) override; + virtual wxFSFile* OpenFile(wxFileSystem& fs, const wxString& location) override; +}; + +#endif // wxUSE_FILESYSTEM + +#endif // _WX_FS_DATA_H_ diff --git a/interface/wx/fs_data.h b/interface/wx/fs_data.h new file mode 100644 index 0000000000..4d6a9f907b --- /dev/null +++ b/interface/wx/fs_data.h @@ -0,0 +1,31 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/fs_data.h +// Purpose: DATA scheme file system +// Author: Vyacheslav Lisovski +// Copyright: (c) 2023 Vyacheslav Lisovski +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +/** + @class wxDataSchemeFSHandler + + File system handler for "data" URI scheme (RFC 2397). + URI syntax: @c "data:[][;base64],". + + The handler makes the data, included (encoded) into URI, available for + components that use the wxFileSystem infrastructure. + + To make available for usage it should be registered somewhere within an + initialization procedure: + @code + wxFileSystem::AddHandler(new wxDataSchemeFSHandler); + @endcode + + @since 3.3.0 +*/ + +class wxDataSchemeFSHandler : public wxFileSystemHandler +{ +public: + wxDataSchemeFSHandler(); +}; diff --git a/src/common/fs_data.cpp b/src/common/fs_data.cpp new file mode 100644 index 0000000000..4eb8b35602 --- /dev/null +++ b/src/common/fs_data.cpp @@ -0,0 +1,126 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/common/fs_data.cpp +// Purpose: DATA scheme file system +// Author: Vyacheslav Lisovski +// Copyright: (c) 2023 Vyacheslav Lisovski +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#include "wx/wxprec.h" + +#if wxUSE_FILESYSTEM + +#include "wx/fs_data.h" + +#include "wx/base64.h" +#include "wx/filesys.h" +#include "wx/mstream.h" +#include "wx/sstream.h" +#include "wx/uri.h" + +namespace +{ + +// This stream holds the buffer and deletes when destroyed +class wxBufferedMemoryInputStream : public wxMemoryInputStream +{ +public: + wxBufferedMemoryInputStream(const wxMemoryBuffer& buffer) : + wxMemoryInputStream(buffer.GetData(), buffer.GetDataLen()), + m_buffer{buffer} + { + } + +private: + wxMemoryBuffer m_buffer; +}; + +// URL syntax: data:[][;base64], +int GetMetadata(const wxString& location, wxString& mediatype, bool& isBase64) +{ + int dataPos = location.Find(','); + if (dataPos > 0) + { + const int hdrPos = location.Find(':'); + if (hdrPos > 0) + { + wxString metadata(location, hdrPos + 1, dataPos - hdrPos - 1); + + int encPos = metadata.Find(';', true); + + if (encPos > 0) + { + auto encoding = metadata.Right(metadata.Len() - encPos - 1); + if (encoding.IsSameAs("base64", false)) + { + isBase64 = true; + } + else + { + encPos = metadata.Len(); + } + } + else + encPos = metadata.Len(); + + mediatype = metadata.Left(encPos); + } + ++dataPos; + } + return dataPos; +} + +} // anonymous namespace + +// ---------------------------------------------------------------------------- +// wxDataSchemeFSHandler +// ---------------------------------------------------------------------------- + +bool wxDataSchemeFSHandler::CanOpen(const wxString& location) +{ + return GetProtocol(location).IsSameAs("data", false); +} + +wxFSFile* wxDataSchemeFSHandler::OpenFile(wxFileSystem& WXUNUSED(fs), + const wxString& location) +{ + wxString mediatype; + bool isBase64 = false; + int dataPos = GetMetadata(location, mediatype, isBase64); + + if (dataPos < 0) + return nullptr; + + if (mediatype.IsEmpty()) + mediatype = "text/plain"; + + wxInputStream* stream = nullptr; + if (isBase64) + { +#if wxUSE_BASE64 + stream = new wxBufferedMemoryInputStream( + wxBase64Decode(location.Right(location.Len() - dataPos))); +#endif // wxUSE_BASE64 + } + else + { + stream = new wxStringInputStream( + wxURI::Unescape(location.Right(location.Len() - dataPos))); + } + + if (stream) + { + return new wxFSFile(stream, + "", + mediatype, + "" +#if wxUSE_DATETIME + , wxDateTime::Now() +#endif // wxUSE_DATETIME + ); + } + + return nullptr; +} + +#endif // wxUSE_FILESYSTEM diff --git a/tests/allheaders.h b/tests/allheaders.h index 2bd780326d..01368c927e 100644 --- a/tests/allheaders.h +++ b/tests/allheaders.h @@ -152,6 +152,7 @@ #include #include #include +#include #include #include #include diff --git a/tests/filesys/filesystest.cpp b/tests/filesys/filesystest.cpp index 85aaae0317..ceea56cf63 100644 --- a/tests/filesys/filesystest.cpp +++ b/tests/filesys/filesystest.cpp @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////////// // Name: tests/filesys/filesys.cpp // Purpose: wxFileSystem unit test -// Author: Vaclav Slavik +// Author: Vaclav Slavik, Vyacheslav Lisovski // Created: 2004-03-28 // Copyright: (c) 2004 Vaclav Slavik /////////////////////////////////////////////////////////////////////////////// @@ -21,7 +21,9 @@ #if wxUSE_FILESYSTEM +#include "wx/fs_data.h" #include "wx/fs_mem.h" +#include "wx/sstream.h" #include @@ -177,6 +179,51 @@ TEST_CASE("wxFileSystem::UnicodeFileNameToUrlConversion", "[filesys][url][filena CHECK( filename.SameAs(wxFileName::URLToFileName(url)) ); } +TEST_CASE("wxFileSystem::DataSchemeFSHandler", "[filesys][dataschemefshandler][openfile]") +{ + // Install wxDataSchemeFSHandler just for the duration of this test. + class AutoDataSchemeFSHandler + { + public: + AutoDataSchemeFSHandler() : m_handler(new wxDataSchemeFSHandler()) + { + wxFileSystem::AddHandler(m_handler.get()); + } + ~AutoDataSchemeFSHandler() + { + wxFileSystem::RemoveHandler(m_handler.get()); + } + private: + std::unique_ptr const m_handler; + } autoDataSchemeFSHandler; + + wxFileSystem fs; + + const struct wxTestCaseData + { + const char *info, *input, *result1, *result2; + } testData[] = + { + { "Testing minimal URI with data", + "data:,the%20data", "text/plain", "the data" }, + { "Testing base64 encoded", + "data:x-t1/x-s1;base64,SGVsbG8sIFdvcmxkIQ==", "x-t1/x-s1", "Hello, World!" }, + { "Testing complex media type", + "data:image/svg+xml;utf8,", "image/svg+xml;utf8", "" } + }; + + for ( const auto& dataItem : testData ) + { + INFO(dataItem.info); + std::unique_ptr file(fs.OpenFile(dataItem.input)); + CHECK(file->GetMimeType() == dataItem.result1); + + wxStringOutputStream sos; + sos.Write(*file->GetStream()); + CHECK(sos.GetString () == dataItem.result2); + } +} + // Test that using FindFirst() after removing a previously found URL works: // this used to be broken, see https://github.com/wxWidgets/wxWidgets/issues/18744 TEST_CASE("wxFileSystem::MemoryFSHandler", "[filesys][memoryfshandler][find]") From 7adcc8f954c1a273d12f92a317565cc2ba75f373 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 19 Dec 2023 02:11:06 +0100 Subject: [PATCH 069/257] Don't use arm64 for universal binaries by default under macOS 10 This architecture is supported since macOS 11. --- configure.ac | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 0d153fd654..f00975fd0b 100644 --- a/configure.ac +++ b/configure.ac @@ -1161,8 +1161,14 @@ if test "x$wxUSE_UNIVERSAL_BINARY" != xno ; then if test "x$wxUSE_UNIVERSAL_BINARY" != xyes; then OSX_ARCH_OPTS=$wxUSE_UNIVERSAL_BINARY else - dnl Default architectures for the universal binaries. - OSX_ARCH_OPTS=arm64,x86_64 + dnl Use default architectures for the universal binaries: x86_64 is + dnl currently supported everywhere... + OSX_ARCH_OPTS=x86_64 + + dnl ... and non-ancient macOS versions also support ARM. + if [ `sw_vers -productVersion | sed 's/\..*//'` -gt 10 ]; then + OSX_ARCH_OPTS=arm64,$OSX_ARCH_OPTS + fi fi AC_MSG_CHECKING([for architectures to use in universal binary]) From 44248eb78a815b3cb61a7179c360f2a88bb2858b Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 21 Dec 2023 12:31:25 -0800 Subject: [PATCH 070/257] Support setting thickness when creating wxGauge with GTK >= 3.20 This stopped working in GTK 3.14, but became possible to fix in 3.20 with the addition of the "min-width"/"min-height" properties. See #24107 --- src/gtk/gauge.cpp | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/gtk/gauge.cpp b/src/gtk/gauge.cpp index 52c8690ff0..56ff299dde 100644 --- a/src/gtk/gauge.cpp +++ b/src/gtk/gauge.cpp @@ -39,7 +39,8 @@ bool wxGauge::Create( wxWindow *parent, m_widget = gtk_progress_bar_new(); g_object_ref(m_widget); - if ( style & wxGA_VERTICAL ) + const bool isVertical = (style & wxGA_VERTICAL) != 0; + if (isVertical) { #ifdef __WXGTK3__ gtk_orientable_set_orientation(GTK_ORIENTABLE(m_widget), GTK_ORIENTATION_VERTICAL); @@ -56,6 +57,29 @@ bool wxGauge::Create( wxWindow *parent, m_parent->DoAddChild( this ); PostCreation(size); +#ifdef __WXGTK3__ + int wh = isVertical ? size.x : size.y; + if (wh > 0 && gtk_check_version(3,20,0) == nullptr) + { + GtkCssProvider* provider = gtk_css_provider_new(); + const char* whStr = isVertical ? "width" : "height"; + char buf[40]; + snprintf(buf, sizeof(buf), "*{min-%s:%dpx}", whStr, wh); + GTKApplyCssStyle(provider, buf); + + int min; + if (isVertical) + gtk_widget_get_preferred_width(m_widget, &min, nullptr); + else + gtk_widget_get_preferred_height(m_widget, &min, nullptr); + + // Adjust the min{width,height} to get the right overall size + wh -= min - wh; + snprintf(buf, sizeof(buf), "*{min-%s:%dpx}", whStr, wxMax(wh, 1)); + GTKApplyCssStyle(provider, buf); + g_object_unref(provider); + } +#endif SetInitialSize(size); return true; From 1bf80138e9855694b25ba9a3fe33aa9d450469aa Mon Sep 17 00:00:00 2001 From: Scott Hanson Date: Tue, 19 Dec 2023 14:58:50 -0500 Subject: [PATCH 071/257] Fix wxDir compilation with wxUSE_STD_STRING_CONV_IN_WXSTRING When enabling this build option, implicit conversion to wchar_t * is not available, so convert wxString to it explicitly. Closes #24149. --- src/msw/dir.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/msw/dir.cpp b/src/msw/dir.cpp index a842a08b9a..074e6008a7 100644 --- a/src/msw/dir.cpp +++ b/src/msw/dir.cpp @@ -75,7 +75,7 @@ CheckFoundMatch(const FIND_STRUCT* finddata, const wxString& filter) if ( filter.empty() ) return true; - return ::PathMatchSpec(finddata->cFileName, filter) == TRUE; + return ::PathMatchSpec(finddata->cFileName, filter.t_str()) == TRUE; } inline bool From f80e2459de549a4192aba8281557bdacf6950921 Mon Sep 17 00:00:00 2001 From: mcorino Date: Fri, 22 Dec 2023 11:47:59 +0100 Subject: [PATCH 072/257] Fix missing semicolon in HasMultipleSelection() documentation Missing semicolon on latest method addition causes doxygen parsing issues which in turn causes problems for dependent projects like wxRuby and wxPython. Closes #24155. --- interface/wx/listbox.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/wx/listbox.h b/interface/wx/listbox.h index 4f96159f00..a21f0f2674 100644 --- a/interface/wx/listbox.h +++ b/interface/wx/listbox.h @@ -165,7 +165,7 @@ public: /** return true if the listbox allows multiple selection */ - bool HasMultipleSelection() const + bool HasMultipleSelection() const; /** Deselects an item in the list box. From 33de6dce6fb74b5cf47a9eb325ed2ce74590fd1d Mon Sep 17 00:00:00 2001 From: mcorino Date: Fri, 22 Dec 2023 12:00:47 +0100 Subject: [PATCH 073/257] Fix confusing wxPersistentTLW ctor argument name Fix an obvious copy/paste error. Closes #24156. --- interface/wx/persist/toplevel.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/wx/persist/toplevel.h b/interface/wx/persist/toplevel.h index 7094fc57a5..c8c4a7c822 100644 --- a/interface/wx/persist/toplevel.h +++ b/interface/wx/persist/toplevel.h @@ -21,10 +21,10 @@ public: /** Constructor. - @param book + @param topwin The associated window. */ - wxPersistentTLW(wxTopLevelWindow *book); + wxPersistentTLW(wxTopLevelWindow *topwin); /** Save the current window geometry. From a059061eb7085fd30e66060700f9b687dce73a5f Mon Sep 17 00:00:00 2001 From: Blake-Madden Date: Wed, 20 Dec 2023 11:23:59 -0500 Subject: [PATCH 074/257] Replace wxDECLARE_NO_COPY_CLASS with deleted functions in samples Use standard C++11 way of making classes non-copyable instead of wx-specific macro. Closes #24150. --- samples/collpane/collpane.cpp | 12 ++++++++---- samples/dataview/mymodels.h | 4 ++-- samples/debugrpt/debugrpt.cpp | 7 ++++--- samples/dialogs/dialogs.cpp | 7 ++++--- samples/dialogs/dialogs.h | 3 ++- samples/docview/doc.h | 14 +++++++++----- samples/docview/docview.h | 3 ++- samples/docview/view.h | 4 ++-- samples/grid/griddemo.cpp | 11 ++++++----- samples/htlbox/htlbox.cpp | 3 ++- samples/html/test/test.cpp | 3 ++- samples/image/image.cpp | 8 ++++---- samples/ipc/baseserver.cpp | 4 ++-- samples/listctrl/listtest.h | 13 +++++++------ samples/mdi/mdi.h | 8 ++++---- samples/opengl/isosurf/isosurf.h | 3 ++- samples/opengl/penguin/penguin.h | 3 ++- samples/splitter/splitter.cpp | 16 ++++++++++------ samples/widgets/itemcontainer.cpp | 4 ++-- samples/widgets/widgets.cpp | 4 ++-- 20 files changed, 78 insertions(+), 56 deletions(-) diff --git a/samples/collpane/collpane.cpp b/samples/collpane/collpane.cpp index 69f7ec8d0e..7c6e0d5a1a 100644 --- a/samples/collpane/collpane.cpp +++ b/samples/collpane/collpane.cpp @@ -71,16 +71,19 @@ class MyApp: public wxApp { public: MyApp() { } + MyApp(const MyApp&) = delete; + MyApp& operator=(const MyApp&) = delete; virtual bool OnInit() override; - - wxDECLARE_NO_COPY_CLASS(MyApp); }; class MyFrame: public wxFrame { public: MyFrame(); + MyFrame(const MyFrame&) = delete; + MyFrame& operator=(const MyFrame&) = delete; + virtual ~MyFrame(); // Menu commands @@ -103,13 +106,15 @@ private: wxBoxSizer *m_paneSizer; wxDECLARE_EVENT_TABLE(); - wxDECLARE_NO_COPY_CLASS(MyFrame); }; class MyDialog : public wxDialog { public: MyDialog(wxFrame *parent); + MyDialog(const MyDialog&) = delete; + MyDialog& operator=(const MyDialog&) = delete; + void OnToggleStatus(wxCommandEvent& WXUNUSED(ev)); void OnAlignButton(wxCommandEvent& WXUNUSED(ev)); void OnPaneChanged(wxCollapsiblePaneEvent& event); @@ -119,7 +124,6 @@ private: wxGridSizer *m_paneSizer; wxDECLARE_EVENT_TABLE(); - wxDECLARE_NO_COPY_CLASS(MyDialog); }; diff --git a/samples/dataview/mymodels.h b/samples/dataview/mymodels.h index 40f86e6666..f4467de67d 100644 --- a/samples/dataview/mymodels.h +++ b/samples/dataview/mymodels.h @@ -245,6 +245,8 @@ class MyIndexListModel : public wxDataViewIndexListModel { public: MyIndexListModel() { } + MyIndexListModel(const MyIndexListModel&) = delete; + MyIndexListModel& operator=(const MyIndexListModel&) = delete; void Fill(const wxArrayString& strings) { @@ -266,8 +268,6 @@ public: private: wxArrayString m_strings; - - wxDECLARE_NO_COPY_CLASS(MyIndexListModel); }; enum ModelFlags diff --git a/samples/debugrpt/debugrpt.cpp b/samples/debugrpt/debugrpt.cpp index 89f7bb2eef..9dcced128f 100644 --- a/samples/debugrpt/debugrpt.cpp +++ b/samples/debugrpt/debugrpt.cpp @@ -157,6 +157,8 @@ class MyFrame : public wxFrame { public: MyFrame(); + MyFrame(const MyFrame&) = delete; + MyFrame& operator=(const MyFrame&) = delete; private: void OnListLoadedDLLs(wxCommandEvent& event); @@ -185,7 +187,6 @@ private: // number of lines drawn in OnPaint() int m_numLines; - wxDECLARE_NO_COPY_CLASS(MyFrame); wxDECLARE_EVENT_TABLE(); }; @@ -202,6 +203,8 @@ class MyApp : public wxApp public: // call wxHandleFatalExceptions here MyApp(); + MyApp(const MyApp&) = delete; + MyApp& operator=(const MyApp&) = delete; // create our main window here virtual bool OnInit() override; @@ -219,8 +222,6 @@ public: private: bool m_uploadReport; - - wxDECLARE_NO_COPY_CLASS(MyApp); }; wxIMPLEMENT_APP(MyApp); diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index a49ce3da85..e493326d93 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -1318,6 +1318,8 @@ public: sizerBtns->Add(new wxButton(this, wxID_RESET, "&Reset all"), wxSizerFlags().Border(wxLEFT)); } + MyRearrangeDialog(const MyRearrangeDialog&) = delete; + MyRearrangeDialog& operator=(const MyRearrangeDialog&) = delete; // call this instead of ShowModal() to update order and labels array in // case the dialog was not cancelled @@ -1409,7 +1411,6 @@ private: wxTextCtrl *m_text; wxDECLARE_EVENT_TABLE(); - wxDECLARE_NO_COPY_CLASS(MyRearrangeDialog); }; wxBEGIN_EVENT_TABLE(MyRearrangeDialog, wxRearrangeDialog) @@ -1731,6 +1732,8 @@ public: : m_dialog(&dialog) { } + MyCustomizeHook(const MyCustomizeHook&) = delete; + MyCustomizeHook& operator=(const MyCustomizeHook&) = delete; // Override pure virtual base class method to add our custom controls. virtual void AddCustomControls(wxFileDialogCustomize& customizer) override @@ -1804,8 +1807,6 @@ private: wxFileDialogStaticText* m_label; wxString m_info; - - wxDECLARE_NO_COPY_CLASS(MyCustomizeHook); }; void MyFrame::FileOpen(wxCommandEvent& WXUNUSED(event) ) diff --git a/samples/dialogs/dialogs.h b/samples/dialogs/dialogs.h index eab880b7d8..a1471d22a5 100644 --- a/samples/dialogs/dialogs.h +++ b/samples/dialogs/dialogs.h @@ -190,6 +190,8 @@ class TestMessageBoxDialog : public wxDialog { public: TestMessageBoxDialog(wxWindow *parent); + TestMessageBoxDialog(const TestMessageBoxDialog&) = delete; + TestMessageBoxDialog& operator=(const TestMessageBoxDialog&) = delete; bool Create(); @@ -256,7 +258,6 @@ private: wxStaticText *m_labelResult; wxDECLARE_EVENT_TABLE(); - wxDECLARE_NO_COPY_CLASS(TestMessageBoxDialog); }; #if wxUSE_RICHMSGDLG diff --git a/samples/docview/doc.h b/samples/docview/doc.h index f5fc6938ad..4b1753300e 100644 --- a/samples/docview/doc.h +++ b/samples/docview/doc.h @@ -164,6 +164,8 @@ class wxTextDocument : public wxDocument { public: wxTextDocument() : wxDocument() { } + wxTextDocument(const wxTextDocument&) = delete; + wxTextDocument &operator=(const wxTextDocument&) = delete; virtual bool OnCreate(const wxString& path, long flags) override; @@ -178,7 +180,6 @@ protected: void OnTextChange(wxCommandEvent& event); - wxDECLARE_NO_COPY_CLASS(wxTextDocument); wxDECLARE_ABSTRACT_CLASS(wxTextDocument); }; @@ -190,9 +191,11 @@ class TextEditDocument : public wxTextDocument { public: TextEditDocument() : wxTextDocument() { } + TextEditDocument(const TextEditDocument&) = delete; + TextEditDocument &operator=(const TextEditDocument&) = delete; + virtual wxTextCtrl* GetTextCtrl() const override; - wxDECLARE_NO_COPY_CLASS(TextEditDocument); wxDECLARE_DYNAMIC_CLASS(TextEditDocument); }; @@ -207,6 +210,8 @@ class ImageDocument : public wxDocument { public: ImageDocument() : wxDocument() { } + ImageDocument(const ImageDocument&) = delete; + ImageDocument &operator=(const ImageDocument&) = delete; virtual bool OnOpenDocument(const wxString& file) override; @@ -218,7 +223,6 @@ protected: private: wxImage m_image; - wxDECLARE_NO_COPY_CLASS(ImageDocument); wxDECLARE_DYNAMIC_CLASS(ImageDocument); }; @@ -229,6 +233,8 @@ class ImageDetailsDocument : public wxDocument { public: ImageDetailsDocument(ImageDocument *parent); + ImageDetailsDocument(const ImageDetailsDocument&) = delete; + ImageDetailsDocument &operator=(const ImageDetailsDocument&) = delete; // accessors for ImageDetailsView wxSize GetSize() const { return m_size; } @@ -242,8 +248,6 @@ private: unsigned long m_numColours; wxBitmapType m_type; bool m_hasAlpha; - - wxDECLARE_NO_COPY_CLASS(ImageDetailsDocument); }; #endif // _WX_SAMPLES_DOCVIEW_DOC_H_ diff --git a/samples/docview/docview.h b/samples/docview/docview.h index 49a531896f..fe5e2cabe2 100644 --- a/samples/docview/docview.h +++ b/samples/docview/docview.h @@ -35,6 +35,8 @@ public: }; MyApp(); + MyApp(const MyApp&) = delete; + MyApp& operator=(const MyApp&) = delete; // override some wxApp virtual methods virtual bool OnInit() override; @@ -90,7 +92,6 @@ private: wxMenu *m_menuEdit; wxDECLARE_EVENT_TABLE(); - wxDECLARE_NO_COPY_CLASS(MyApp); }; wxDECLARE_APP(MyApp); diff --git a/samples/docview/view.h b/samples/docview/view.h index af587492d2..baefee6baa 100644 --- a/samples/docview/view.h +++ b/samples/docview/view.h @@ -155,14 +155,14 @@ class ImageDetailsView : public wxView { public: ImageDetailsView(ImageDetailsDocument *doc); + ImageDetailsView(const ImageDetailsView&) = delete; + ImageDetailsView& operator=(const ImageDetailsView&) = delete; virtual void OnDraw(wxDC *dc) override; virtual bool OnClose(bool deleteWindow) override; private: wxFrame *m_frame; - - wxDECLARE_NO_COPY_CLASS(ImageDetailsView); }; #endif // _WX_SAMPLES_DOCVIEW_VIEW_H_ diff --git a/samples/grid/griddemo.cpp b/samples/grid/griddemo.cpp index e0a21882bc..b4cea19e54 100644 --- a/samples/grid/griddemo.cpp +++ b/samples/grid/griddemo.cpp @@ -49,6 +49,8 @@ public: m_colBg(colBg) { } + CustomColumnHeaderRenderer(const CustomColumnHeaderRenderer&) = delete; + CustomColumnHeaderRenderer& operator=(const CustomColumnHeaderRenderer&) = delete; virtual void DrawLabel(const wxGrid& WXUNUSED(grid), wxDC& dc, @@ -74,8 +76,6 @@ public: private: const wxColour m_colFg, m_colBg; - - wxDECLARE_NO_COPY_CLASS(CustomColumnHeaderRenderer); }; // And a custom attributes provider which uses custom column header renderer @@ -91,6 +91,8 @@ public: m_useCustom(false) { } + CustomColumnHeadersProvider(const CustomColumnHeadersProvider&) = delete; + CustomColumnHeadersProvider& operator=(const CustomColumnHeadersProvider&) = delete; // enable or disable the use of custom renderer for column headers void UseCustomColHeaders(bool use = true) { m_useCustom = use; } @@ -114,8 +116,6 @@ private: m_customEvenRenderer; bool m_useCustom; - - wxDECLARE_NO_COPY_CLASS(CustomColumnHeadersProvider); }; // ---------------------------------------------------------------------------- @@ -2437,6 +2437,8 @@ class TabularGridFrame : public wxFrame { public: TabularGridFrame(); + TabularGridFrame(const TabularGridFrame&) = delete; + TabularGridFrame& operator=(const TabularGridFrame&) = delete; private: enum // control ids @@ -2626,7 +2628,6 @@ private: bool m_shouldUpdateRowOrder, m_shouldUpdateColOrder; - wxDECLARE_NO_COPY_CLASS(TabularGridFrame); wxDECLARE_EVENT_TABLE(); }; diff --git a/samples/htlbox/htlbox.cpp b/samples/htlbox/htlbox.cpp index 571cab0c68..a760ea245d 100644 --- a/samples/htlbox/htlbox.cpp +++ b/samples/htlbox/htlbox.cpp @@ -60,6 +60,8 @@ class MyHtmlListBox : public wxHtmlListBox public: MyHtmlListBox() { } MyHtmlListBox(wxWindow *parent, bool multi = false); + MyHtmlListBox(const MyHtmlListBox&) = delete; + MyHtmlListBox& operator=(const MyHtmlListBox&) = delete; void SetChangeSelFg(bool change) { m_change = change; } void UpdateFirstItem(); @@ -90,7 +92,6 @@ public: wxTextFile m_file; #endif - wxDECLARE_NO_COPY_CLASS(MyHtmlListBox); wxDECLARE_DYNAMIC_CLASS(MyHtmlListBox); }; diff --git a/samples/html/test/test.cpp b/samples/html/test/test.cpp index c5402495e9..509887c54e 100644 --- a/samples/html/test/test.cpp +++ b/samples/html/test/test.cpp @@ -50,6 +50,8 @@ public: // no custom background initially to avoid confusing people m_drawCustomBg = false; } + MyHtmlWindow(const MyHtmlWindow&) = delete; + MyHtmlWindow& operator=(const MyHtmlWindow&) = delete; virtual wxHtmlOpeningStatus OnOpeningURL(wxHtmlURLType WXUNUSED(type), const wxString& WXUNUSED(url), @@ -71,7 +73,6 @@ private: bool m_drawCustomBg; wxDECLARE_EVENT_TABLE(); - wxDECLARE_NO_COPY_CLASS(MyHtmlWindow); }; // Define a new frame type: this is going to be our main frame diff --git a/samples/image/image.cpp b/samples/image/image.cpp index 27ee4975c8..9714b04de9 100644 --- a/samples/image/image.cpp +++ b/samples/image/image.cpp @@ -1261,6 +1261,8 @@ public: Show(); } + MySVGFrame(const MySVGFrame&) = delete; + MySVGFrame& operator=(const MySVGFrame&) = delete; private: void OnPaint(wxPaintEvent&) @@ -1290,8 +1292,6 @@ private: const wxBitmapBundle m_bundle; wxBitmap m_bitmap; - - wxDECLARE_NO_COPY_CLASS(MySVGFrame); }; void MyFrame::OnNewSVGFrame(wxCommandEvent&) @@ -1413,6 +1413,8 @@ public: Show(); } + MyGraphicsFrame(const MyGraphicsFrame&) = delete; + MyGraphicsFrame& operator=(const MyGraphicsFrame&) = delete; private: void OnPaint(wxPaintEvent& WXUNUSED(event)) @@ -1433,8 +1435,6 @@ private: wxImage m_image; wxBitmap m_bitmap; - - wxDECLARE_NO_COPY_CLASS(MyGraphicsFrame); }; void MyFrame::OnTestGraphics(wxCommandEvent& WXUNUSED(event)) diff --git a/samples/ipc/baseserver.cpp b/samples/ipc/baseserver.cpp index 1576ccf735..9898bc284f 100644 --- a/samples/ipc/baseserver.cpp +++ b/samples/ipc/baseserver.cpp @@ -78,6 +78,8 @@ class BenchConnection : public wxConnection { public: BenchConnection() { m_advise = false; } + BenchConnection(const BenchConnection&) = delete; + BenchConnection& operator=(const BenchConnection&) = delete; virtual bool OnPoke(const wxString& topic, const wxString& item, @@ -99,8 +101,6 @@ private: // should we notify the client about changes to m_item? bool m_advise; - - wxDECLARE_NO_COPY_CLASS(BenchConnection); }; // a simple server accepting connections to IPC_TOPIC and IPC_BENCHMARK_TOPIC diff --git a/samples/listctrl/listtest.h b/samples/listctrl/listtest.h index 1538799ebb..4920cba6f5 100644 --- a/samples/listctrl/listtest.h +++ b/samples/listctrl/listtest.h @@ -20,11 +20,10 @@ class MyApp: public wxApp { public: MyApp() { } + MyApp(const MyApp&) = delete; + MyApp& operator=(const MyApp&) = delete; virtual bool OnInit() override; - -private: - wxDECLARE_NO_COPY_CLASS(MyApp); }; class MyListCtrl: public wxListCtrl @@ -40,6 +39,8 @@ public: m_updated = -1; } + MyListCtrl(const MyListCtrl&) = delete; + MyListCtrl &operator=(const MyListCtrl&) = delete; // add one item to the listctrl in report mode void InsertItemInReportView(int i); @@ -90,7 +91,6 @@ private: // checked boxes in virtual list wxSelectionStore m_checked; - wxDECLARE_NO_COPY_CLASS(MyListCtrl); wxDECLARE_EVENT_TABLE(); }; @@ -99,6 +99,9 @@ class MyFrame: public wxFrame { public: MyFrame(const wxString& title); + MyFrame(const MyFrame&) = delete; + MyFrame &operator=(const MyFrame&) = delete; + virtual ~MyFrame(); protected: @@ -185,8 +188,6 @@ private: // number of items to initialize list/report view with int m_numListItems; - - wxDECLARE_NO_COPY_CLASS(MyFrame); wxDECLARE_EVENT_TABLE(); }; diff --git a/samples/mdi/mdi.h b/samples/mdi/mdi.h index 1dee3e51b4..c8e1804e31 100644 --- a/samples/mdi/mdi.h +++ b/samples/mdi/mdi.h @@ -25,6 +25,8 @@ public: m_frame(frame) { } + MenuEventLogger(const MenuEventLogger&) = delete; + MenuEventLogger& operator=(const MenuEventLogger&) = delete; protected: void LogMenuOpenClose(wxMenuEvent& event, const char *action) @@ -52,8 +54,6 @@ protected: const wxString m_label; wxFrame* const m_frame; - - wxDECLARE_NO_COPY_CLASS(MenuEventLogger); }; class MyCanvas : public wxScrolledWindow, @@ -155,6 +155,8 @@ private: { public: EventHandler(unsigned numChild) : m_numChild(numChild) { } + EventHandler(const EventHandler&) = delete; + EventHandler &operator=(const EventHandler&) = delete; private: void OnRefresh(wxCommandEvent& event) @@ -166,8 +168,6 @@ private: const unsigned m_numChild; wxDECLARE_EVENT_TABLE(); - - wxDECLARE_NO_COPY_CLASS(EventHandler); }; wxDECLARE_EVENT_TABLE(); diff --git a/samples/opengl/isosurf/isosurf.h b/samples/opengl/isosurf/isosurf.h index 4a7305d0c6..659b19c3c1 100644 --- a/samples/opengl/isosurf/isosurf.h +++ b/samples/opengl/isosurf/isosurf.h @@ -47,6 +47,8 @@ public: TestGLCanvas(wxWindow *parent, wxWindowID id = wxID_ANY, int *gl_attrib = nullptr); + TestGLCanvas(const TestGLCanvas&) = delete; + TestGLCanvas& operator=(const TestGLCanvas&) = delete; virtual ~TestGLCanvas(); @@ -69,7 +71,6 @@ private: GLfloat m_xrot; GLfloat m_yrot; - wxDECLARE_NO_COPY_CLASS(TestGLCanvas); wxDECLARE_EVENT_TABLE(); }; diff --git a/samples/opengl/penguin/penguin.h b/samples/opengl/penguin/penguin.h index d1bfdc83fb..ca37b2f119 100644 --- a/samples/opengl/penguin/penguin.h +++ b/samples/opengl/penguin/penguin.h @@ -79,6 +79,8 @@ public: const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = 0, const wxString& name = "TestGLCanvas"); + TestGLCanvas(const TestGLCanvas&) = delete; + TestGLCanvas& operator=(const TestGLCanvas&) = delete; virtual ~TestGLCanvas(); @@ -98,7 +100,6 @@ private: GLData m_gldata; DXFRenderer m_renderer; - wxDECLARE_NO_COPY_CLASS(TestGLCanvas); wxDECLARE_EVENT_TABLE(); }; diff --git a/samples/splitter/splitter.cpp b/samples/splitter/splitter.cpp index e6d73e38a4..3d100be780 100644 --- a/samples/splitter/splitter.cpp +++ b/samples/splitter/splitter.cpp @@ -71,16 +71,19 @@ class MyApp: public wxApp { public: MyApp() { } + MyApp(const MyApp&) = delete; + MyApp& operator=(const MyApp&) = delete; virtual bool OnInit() override; - - wxDECLARE_NO_COPY_CLASS(MyApp); }; class MyFrame: public wxFrame { public: MyFrame(); + MyFrame(const MyFrame&) = delete; + MyFrame& operator=(const MyFrame&) = delete; + virtual ~MyFrame(); void ToggleFlag(int flag, bool enable); @@ -136,13 +139,14 @@ private: bool m_allowDClick = true; wxDECLARE_EVENT_TABLE(); - wxDECLARE_NO_COPY_CLASS(MyFrame); }; class MySplitterWindow : public wxSplitterWindow { public: MySplitterWindow(MyFrame *parent); + MySplitterWindow(const MySplitterWindow&) = delete; + MySplitterWindow &operator=(const MySplitterWindow &) = delete; // event handlers void OnPositionChanged(wxSplitterEvent& event); @@ -155,21 +159,21 @@ private: MyFrame *m_frame; wxDECLARE_EVENT_TABLE(); - wxDECLARE_NO_COPY_CLASS(MySplitterWindow); }; class MyCanvas: public wxScrolledWindow { public: MyCanvas(wxWindow* parent, bool mirror); + MyCanvas(const MyCanvas&) = delete; + MyCanvas &operator=(const MyCanvas &) = delete; + virtual ~MyCanvas(){} virtual void OnDraw(wxDC& dc) override; private: bool m_mirror; - - wxDECLARE_NO_COPY_CLASS(MyCanvas); }; // ============================================================================ diff --git a/samples/widgets/itemcontainer.cpp b/samples/widgets/itemcontainer.cpp index 30b02d1c82..47cda198c7 100644 --- a/samples/widgets/itemcontainer.cpp +++ b/samples/widgets/itemcontainer.cpp @@ -40,6 +40,8 @@ public: { m_tracker->StartTrackingData(); } + TrackedClientData(const TrackedClientData&) = delete; + TrackedClientData& operator=(const TrackedClientData&) = delete; virtual ~TrackedClientData() { @@ -54,8 +56,6 @@ public: private: ItemContainerWidgetsPage *m_tracker; int m_value; - - wxDECLARE_NO_COPY_CLASS(TrackedClientData); }; // ============================================================================ diff --git a/samples/widgets/widgets.cpp b/samples/widgets/widgets.cpp index c9d0b41593..b4f186ad19 100644 --- a/samples/widgets/widgets.cpp +++ b/samples/widgets/widgets.cpp @@ -142,6 +142,8 @@ public: m_logTarget = nullptr; #endif // USE_LOG } + WidgetsApp(const WidgetsApp&) = delete; + WidgetsApp& operator=(const WidgetsApp&) = delete; // override base class virtuals // ---------------------------- @@ -158,8 +160,6 @@ private: #if USE_LOG wxLog* m_logTarget; #endif // USE_LOG - - wxDECLARE_NO_COPY_CLASS(WidgetsApp); }; wxDECLARE_APP(WidgetsApp); // This provides a convenient wxGetApp() accessor. From 7c592ba361efabef4b453edb1601866d89225cc9 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 21 Dec 2023 20:45:41 +0100 Subject: [PATCH 075/257] Make WidgetsPage pages scrollable in the widgets sample Because some pages in the sample contain too much content to fit entirely in the visible area of the page. Under wxQt port, this is true regardless of the state of the window (whether it is maximized or not) some content remains hidden and inaccessible. Closes #24154. --- samples/widgets/button.cpp | 4 ++-- samples/widgets/combobox.cpp | 38 ++++++++++++++++++------------------ samples/widgets/widgets.cpp | 8 ++++---- samples/widgets/widgets.h | 4 ++-- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/samples/widgets/button.cpp b/samples/widgets/button.cpp index d9b7b750ee..da02a26668 100644 --- a/samples/widgets/button.cpp +++ b/samples/widgets/button.cpp @@ -374,7 +374,7 @@ void ButtonWidgetsPage::CreateContent() #endif // right pane - m_sizerButton = new wxBoxSizer(wxHORIZONTAL); + m_sizerButton = new wxBoxSizer(wxVERTICAL); m_sizerButton->SetMinSize(FromDIP(150), 0); // the 3 panes panes compose the window @@ -612,7 +612,7 @@ void ButtonWidgetsPage::CreateButton() m_sizerButton->AddStretchSpacer(); m_sizerButton->Add(m_button, wxSizerFlags().Centre().Border()); - m_sizerButton->AddStretchSpacer(); + m_sizerButton->AddStretchSpacer(2); m_sizerButton->Layout(); } diff --git a/samples/widgets/combobox.cpp b/samples/widgets/combobox.cpp index 7f57b10556..af2d78050f 100644 --- a/samples/widgets/combobox.cpp +++ b/samples/widgets/combobox.cpp @@ -259,6 +259,15 @@ void ComboboxWidgetsPage::CreateContent() wxSizer *sizerTop = new wxBoxSizer(wxHORIZONTAL); // upper left pane + wxStaticBoxSizer *sizerLeftTop = new wxStaticBoxSizer(wxVERTICAL, this, "&Popup"); + wxStaticBox* const sizerLeftTopBox = sizerLeftTop->GetStaticBox(); + + sizerLeftTop->Add(new wxButton(sizerLeftTopBox, ComboPage_Popup, "&Show"), + wxSizerFlags().Border().Centre()); + sizerLeftTop->Add(new wxButton(sizerLeftTopBox, ComboPage_Dismiss, "&Hide"), + wxSizerFlags().Border().Centre()); + + // lower left pane // should be in sync with ComboKind_XXX values static const wxString kinds[] = @@ -268,32 +277,23 @@ void ComboboxWidgetsPage::CreateContent() "drop down", }; - wxStaticBoxSizer *sizerLeftTop = new wxStaticBoxSizer(wxVERTICAL, this, "&Set style"); - wxStaticBox* const sizerLeftTopBox = sizerLeftTop->GetStaticBox(); + wxStaticBoxSizer *sizerLeftBottom = new wxStaticBoxSizer(wxVERTICAL, this, "&Set style"); + wxStaticBox* const sizerLeftBottomBox = sizerLeftBottom->GetStaticBox(); - m_radioKind = new wxRadioBox(sizerLeftTopBox, wxID_ANY, "Combobox &kind:", + m_radioKind = new wxRadioBox(sizerLeftBottomBox, wxID_ANY, "Combobox &kind:", wxDefaultPosition, wxDefaultSize, WXSIZEOF(kinds), kinds, 1, wxRA_SPECIFY_COLS); - m_chkSort = CreateCheckBoxAndAddToSizer(sizerLeftTop, "&Sort items", wxID_ANY, sizerLeftTopBox); - m_chkReadonly = CreateCheckBoxAndAddToSizer(sizerLeftTop, "&Read only", wxID_ANY, sizerLeftTopBox); - m_chkProcessEnter = CreateCheckBoxAndAddToSizer(sizerLeftTop, "Process &Enter", wxID_ANY, sizerLeftTopBox); + m_chkSort = CreateCheckBoxAndAddToSizer(sizerLeftBottom, "&Sort items", wxID_ANY, sizerLeftBottomBox); + m_chkReadonly = CreateCheckBoxAndAddToSizer(sizerLeftBottom, "&Read only", wxID_ANY, sizerLeftBottomBox); + m_chkProcessEnter = CreateCheckBoxAndAddToSizer(sizerLeftBottom, "Process &Enter", wxID_ANY, sizerLeftBottomBox); - sizerLeftTop->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer - sizerLeftTop->Add(m_radioKind, 0, wxGROW | wxALL, 5); + sizerLeftBottom->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer + sizerLeftBottom->Add(m_radioKind, 0, wxGROW | wxALL, 5); - wxButton *btn = new wxButton(sizerLeftTopBox, ComboPage_Reset, "&Reset"); - sizerLeftTop->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15); - - // lower left pane - wxStaticBoxSizer *sizerLeftBottom = new wxStaticBoxSizer(wxVERTICAL, this, "&Popup"); - wxStaticBox* const sizerLeftBottomBox = sizerLeftBottom->GetStaticBox(); - - sizerLeftBottom->Add(new wxButton(sizerLeftBottomBox, ComboPage_Popup, "&Show"), - wxSizerFlags().Border().Centre()); - sizerLeftBottom->Add(new wxButton(sizerLeftBottomBox, ComboPage_Dismiss, "&Hide"), - wxSizerFlags().Border().Centre()); + wxButton *btn = new wxButton(sizerLeftBottomBox, ComboPage_Reset, "&Reset"); + sizerLeftBottom->Add(btn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15); wxSizer *sizerLeft = new wxBoxSizer(wxVERTICAL); diff --git a/samples/widgets/widgets.cpp b/samples/widgets/widgets.cpp index b4f186ad19..c2cb886adc 100644 --- a/samples/widgets/widgets.cpp +++ b/samples/widgets/widgets.cpp @@ -771,7 +771,8 @@ void WidgetsFrame::OnPageChanged(WidgetsBookCtrlEvent& event) { wxWindowUpdateLocker noUpdates(curPage); curPage->CreateContent(); - curPage->Layout(); + curPage->SetScrollRate(10, 10); + curPage->FitInside(); ConnectToWidgetEvents(); } @@ -1321,10 +1322,9 @@ WidgetsPageInfo *WidgetsPage::ms_widgetPages = nullptr; WidgetsPage::WidgetsPage(WidgetsBookCtrl *book, wxImageList *imaglist, const char *const icon[]) - : wxPanel(book, wxID_ANY, + : wxScrolledWindow(book, wxID_ANY, wxDefaultPosition, wxDefaultSize, - wxCLIP_CHILDREN | - wxTAB_TRAVERSAL) + wxCLIP_CHILDREN | wxTAB_TRAVERSAL) { imaglist->Add(wxBitmap(wxImage(icon).Scale(ICON_SIZE, ICON_SIZE))); } diff --git a/samples/widgets/widgets.h b/samples/widgets/widgets.h index 3f934cb4d6..c89acaec5c 100644 --- a/samples/widgets/widgets.h +++ b/samples/widgets/widgets.h @@ -46,7 +46,7 @@ class WXDLLIMPEXP_FWD_CORE WidgetsBookCtrl; class WidgetsPageInfo; -#include "wx/panel.h" +#include "wx/scrolwin.h" #include "wx/vector.h" // INTRODUCING NEW PAGES DON'T FORGET TO ADD ENTRIES TO 'WidgetsCategories' @@ -119,7 +119,7 @@ struct WidgetAttributes long m_defaultFlags; }; -class WidgetsPage : public wxPanel +class WidgetsPage : public wxScrolledWindow { public: WidgetsPage(WidgetsBookCtrl *book, From 27585bf2c3f0366153c1aa3e7102959f466039b3 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 22 Dec 2023 17:40:00 +0100 Subject: [PATCH 076/257] Hardcode minimal widget sample notebook size Not doing this resulted in the window being tiny by default, so it's better than nothing, even if it's clearly still not ideal. See #24154. --- samples/widgets/widgets.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/samples/widgets/widgets.cpp b/samples/widgets/widgets.cpp index c2cb886adc..263e8ddac5 100644 --- a/samples/widgets/widgets.cpp +++ b/samples/widgets/widgets.cpp @@ -506,8 +506,9 @@ WidgetsFrame::WidgetsFrame(const wxString& title) // Uncomment to suppress page theme (draw in solid colour) //style |= wxNB_NOPAGETHEME; + // Give it some reasonably big minimal size by default. m_book = new WidgetsBookCtrl(m_panel, Widgets_BookCtrl, - wxDefaultPosition, wxDefaultSize, + wxDefaultPosition, FromDIP(wxSize(900, 500)), style, "Widgets"); InitBook(); From 99434fa005c790a10b43947d5b286a44af90847c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 22 Dec 2023 18:43:57 +0100 Subject: [PATCH 077/257] Add wx/persist/combobox.h to the headers list In particular this ensures that it is installed by "make install". See #24157. --- Makefile.in | 1 + build/bakefiles/files.bkl | 1 + build/cmake/files.cmake | 1 + build/files | 1 + build/msw/wx_core.vcxproj | 1 + build/msw/wx_core.vcxproj.filters | 3 +++ 6 files changed, 8 insertions(+) diff --git a/Makefile.in b/Makefile.in index 67bdae4306..d000d08142 100644 --- a/Makefile.in +++ b/Makefile.in @@ -3894,6 +3894,7 @@ COND_USE_GUI_1_ALL_GUI_HEADERS = \ wx/bmpbndl.h \ wx/filedlgcustomize.h \ wx/compositebookctrl.h \ + wx/persist/combobox.h \ $(LOWLEVEL_HDR) \ $(GUI_CORE_HEADERS) \ wx/mediactrl.h \ diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index ba64fd032a..204afb5c45 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -1324,6 +1324,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/bmpbndl.h wx/filedlgcustomize.h wx/compositebookctrl.h + wx/persist/combobox.h diff --git a/build/cmake/files.cmake b/build/cmake/files.cmake index 691d5e744e..25be771479 100644 --- a/build/cmake/files.cmake +++ b/build/cmake/files.cmake @@ -1225,6 +1225,7 @@ set(GUI_CMN_HDR wx/bmpbndl.h wx/filedlgcustomize.h wx/compositebookctrl.h + wx/persist/combobox.h ) set(UNIX_SRC diff --git a/build/files b/build/files index 730b5c8124..536ec62d8a 100644 --- a/build/files +++ b/build/files @@ -1152,6 +1152,7 @@ GUI_CMN_HDR = wx/peninfobase.h wx/persist.h wx/persist/bookctrl.h + wx/persist/combobox.h wx/persist/dataview.h wx/persist/splitter.h wx/persist/toplevel.h diff --git a/build/msw/wx_core.vcxproj b/build/msw/wx_core.vcxproj index 5ff159b0b2..746c6ff8d6 100644 --- a/build/msw/wx_core.vcxproj +++ b/build/msw/wx_core.vcxproj @@ -1518,6 +1518,7 @@ + diff --git a/build/msw/wx_core.vcxproj.filters b/build/msw/wx_core.vcxproj.filters index 3d8baa65f3..4ad1ecdedd 100644 --- a/build/msw/wx_core.vcxproj.filters +++ b/build/msw/wx_core.vcxproj.filters @@ -2056,6 +2056,9 @@ Common Headers + + Common Headers + Common Headers From 6dd129049fd13d793afd91399b2ccfbe38ddd9c5 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Fri, 22 Dec 2023 22:46:54 +0100 Subject: [PATCH 078/257] Initialize array for wxPropertyGrid alphabetic mode only once Array holding items to use in non-categoric mode should be created and initially populated only once. Closes #24145. --- include/wx/propgrid/propgridpagestate.h | 1 - src/propgrid/propgridpagestate.cpp | 14 ++++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/wx/propgrid/propgridpagestate.h b/include/wx/propgrid/propgridpagestate.h index 67f93869a1..60904042dd 100644 --- a/include/wx/propgrid/propgridpagestate.h +++ b/include/wx/propgrid/propgridpagestate.h @@ -813,7 +813,6 @@ protected: bool m_dontCenterSplitter; private: - // Only inits arrays, doesn't migrate things or such. void InitNonCatMode(); }; diff --git a/src/propgrid/propgridpagestate.cpp b/src/propgrid/propgridpagestate.cpp index e5e29f793f..e69b0d4a52 100644 --- a/src/propgrid/propgridpagestate.cpp +++ b/src/propgrid/propgridpagestate.cpp @@ -219,12 +219,14 @@ wxPropertyGridPageState::~wxPropertyGridPageState() void wxPropertyGridPageState::InitNonCatMode() { - if ( !m_abcArray ) - { - m_abcArray = new wxPGRootProperty(wxS("")); - m_abcArray->SetParentState(this); - m_abcArray->SetFlag(wxPG_PROP_CHILDREN_ARE_COPIES); - } + // Initialize and populate array holding properties in alphabetic (non-categoric) + // mode only once. + if (m_abcArray) + return; + + m_abcArray = new wxPGRootProperty(wxS("")); + m_abcArray->SetParentState(this); + m_abcArray->SetFlag(wxPG_PROP_CHILDREN_ARE_COPIES); // Must be called when state::m_properties still points to regularArray. wxPGProperty* oldProperties = m_properties; From 1b5a43599a7dcb8f4def3d6a54af3fb504430b0a Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Fri, 22 Dec 2023 23:00:05 +0100 Subject: [PATCH 079/257] Preserve wxPGProperty parent while adding property to alphabetic items array Real wxPGProperty parent has to be preserved for wxPropertyGridIterator to work properly. --- src/propgrid/propgridpagestate.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/propgrid/propgridpagestate.cpp b/src/propgrid/propgridpagestate.cpp index e69b0d4a52..558030f6a7 100644 --- a/src/propgrid/propgridpagestate.cpp +++ b/src/propgrid/propgridpagestate.cpp @@ -248,7 +248,8 @@ void wxPropertyGridPageState::InitNonCatMode() if ( parent->IsCategory() || parent->IsRoot() ) { m_abcArray->DoAddChild(p); - p->m_parent = &m_regularArray; + // Restore parent modified in AddChild() + p->m_parent = parent; } } } From 550849b78615a80f615140f74635a67c52b82cfe Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 02:26:39 +0100 Subject: [PATCH 080/257] Allow adding and deleting notebook tabs in the AUI sample This is useful for testing that wxAuiNotebook updates correctly when this is done. --- samples/aui/auidemo.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/samples/aui/auidemo.cpp b/samples/aui/auidemo.cpp index 6eeee9a118..f8fd21cca1 100644 --- a/samples/aui/auidemo.cpp +++ b/samples/aui/auidemo.cpp @@ -24,6 +24,7 @@ #include "wx/dataobj.h" #include "wx/dcclient.h" #include "wx/bmpbuttn.h" +#include "wx/log.h" #include "wx/menu.h" #include "wx/toolbar.h" #include "wx/statusbr.h" @@ -98,6 +99,8 @@ class MyFrame : public wxFrame ID_NotebookArtSimple, ID_NotebookAlignTop, ID_NotebookAlignBottom, + ID_NotebookNewTab, + ID_NotebookDeleteTab, ID_SampleItem, @@ -158,6 +161,9 @@ private: void OnNotebookFlag(wxCommandEvent& evt); void OnUpdateUI(wxUpdateUIEvent& evt); + void OnNotebookNewTab(wxCommandEvent& evt); + void OnNotebookDeleteTab(wxCommandEvent& evt); + void OnPaneClose(wxAuiManagerEvent& evt); private: @@ -605,6 +611,8 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(ID_NotebookArtSimple, MyFrame::OnNotebookFlag) EVT_MENU(ID_NotebookAlignTop, MyFrame::OnTabAlignment) EVT_MENU(ID_NotebookAlignBottom, MyFrame::OnTabAlignment) + EVT_MENU(ID_NotebookNewTab, MyFrame::OnNotebookNewTab) + EVT_MENU(ID_NotebookDeleteTab, MyFrame::OnNotebookDeleteTab) EVT_MENU(ID_NoGradient, MyFrame::OnGradient) EVT_MENU(ID_VerticalGradient, MyFrame::OnGradient) EVT_MENU(ID_HorizontalGradient, MyFrame::OnGradient) @@ -733,6 +741,9 @@ MyFrame::MyFrame(wxWindow* parent, notebook_menu->AppendCheckItem(ID_NotebookScrollButtons, _("Scroll Buttons Visible")); notebook_menu->AppendCheckItem(ID_NotebookWindowList, _("Window List Button Visible")); notebook_menu->AppendCheckItem(ID_NotebookTabFixedWidth, _("Fixed-width Tabs")); + notebook_menu->AppendSeparator(); + notebook_menu->Append(ID_NotebookNewTab, _("Add a &New Tab")); + notebook_menu->Append(ID_NotebookDeleteTab, _("&Delete Last Tab")); m_perspectives_menu = new wxMenu; m_perspectives_menu->Append(ID_CreatePerspective, _("Create Perspective")); @@ -1300,6 +1311,36 @@ void MyFrame::OnUpdateUI(wxUpdateUIEvent& event) } } + +void MyFrame::OnNotebookNewTab(wxCommandEvent& WXUNUSED(evt)) +{ + auto* const book = + wxCheckCast(m_mgr.GetPane("notebook_content").window); + + book->AddPage(new wxTextCtrl(book, wxID_ANY, "New Tab", + wxDefaultPosition, wxDefaultSize, + wxTE_MULTILINE | wxNO_BORDER), + wxString::Format("Tab %zu", book->GetPageCount() + 1), + true /* select */); +} + + +void MyFrame::OnNotebookDeleteTab(wxCommandEvent& WXUNUSED(evt)) +{ + auto* const book = + wxCheckCast(m_mgr.GetPane("notebook_content").window); + + auto numPages = book->GetPageCount(); + if ( !numPages ) + { + wxLogWarning("No pages to delete."); + return; + } + + book->DeletePage(numPages - 1); +} + + void MyFrame::OnPaneClose(wxAuiManagerEvent& evt) { if (evt.pane->name == "test10") From a2120bb6e12eecfeca8100c6217cde55d7682fb9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 02:27:37 +0100 Subject: [PATCH 081/257] Factor out wxAuiTabContainer::GetCloseButtonState() Extract the function for determining whether the close button should be shown for the given page in a reusable function. No real changes yet. --- include/wx/aui/auibook.h | 3 +++ src/aui/auibook.cpp | 22 ++++++++++------------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/include/wx/aui/auibook.h b/include/wx/aui/auibook.h index 8f79f8f576..7caef20bbb 100644 --- a/include/wx/aui/auibook.h +++ b/include/wx/aui/auibook.h @@ -189,6 +189,9 @@ protected: wxRect m_rect; size_t m_tabOffset; unsigned int m_flags; + +private: + int GetCloseButtonState(const wxAuiNotebookPage& page) const; }; diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 035e763edb..570819219c 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -400,6 +400,15 @@ void wxAuiTabContainer::SetTabOffset(size_t offset) +int wxAuiTabContainer::GetCloseButtonState(const wxAuiNotebookPage& page) const +{ + // determine if a close button is on this tab + return ((m_flags & wxAUI_NB_CLOSE_ON_ALL_TABS) != 0 || + ((m_flags & wxAUI_NB_CLOSE_ON_ACTIVE_TAB) != 0 && page.active)) + ? wxAUI_BUTTON_STATE_NORMAL + : wxAUI_BUTTON_STATE_HIDDEN; +} + // Render() renders the tab catalog to the specified DC // It is a virtual function and can be overridden to @@ -446,24 +455,13 @@ void wxAuiTabContainer::Render(wxDC* raw_dc, wxWindow* wnd) { wxAuiNotebookPage& page = m_pages.Item(i); - // determine if a close button is on this tab - bool close_button = false; - if ((m_flags & wxAUI_NB_CLOSE_ON_ALL_TABS) != 0 || - ((m_flags & wxAUI_NB_CLOSE_ON_ACTIVE_TAB) != 0 && page.active)) - { - close_button = true; - } - - int x_extent = 0; wxSize size = m_art->GetTabSize(dc, wnd, page.caption, page.bitmap, page.active, - close_button ? - wxAUI_BUTTON_STATE_NORMAL : - wxAUI_BUTTON_STATE_HIDDEN, + GetCloseButtonState(page), &x_extent); if (i+1 < page_count) From 5ae2e3593e82297824e23285ee90d93ae781503c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 02:28:16 +0100 Subject: [PATCH 082/257] Fix close button handling in wxAuiTabContainer::IsTabVisible() The existing code didn't work correctly when wxAUI_NB_CLOSE_ON_ALL_TABS style was used as it didn't check for it and so assumed that the close button was only shown on the current page. This resulted in wrong result being returned from this function for the right most tab which could not actually fit into the available space when rendered (because Render() did draw all close buttons correctly) and, because of this, not showing the tab entirely when MakeTabVisible() was called, e.g. when adding a new tab. Closes #24096. --- src/aui/auibook.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 570819219c..2f2d3939cf 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -796,7 +796,6 @@ bool wxAuiTabContainer::IsTabVisible(int tabPage, int tabOffset, wxDC* dc, wxWin for (i = tabOffset; i < page_count; ++i) { wxAuiNotebookPage& page = m_pages.Item(i); - wxAuiTabContainerButton& tab_button = m_tabCloseButtons.Item(i); rect.width = m_rect.width - right_buttons_width - offset - wnd->FromDIP(2); @@ -809,7 +808,7 @@ bool wxAuiTabContainer::IsTabVisible(int tabPage, int tabOffset, wxDC* dc, wxWin page.caption, page.bitmap, page.active, - tab_button.curState, + GetCloseButtonState(page), &x_extent); offset += x_extent; From b458e05502944b1619645fabb62cbcccacfe9388 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 03:06:48 +0100 Subject: [PATCH 083/257] Revert "Fix user-visible with AUI tab selection after dragging" This reverts commit b1fcf100fff53dad8feac9fea808bc5842fc385a because it doesn't seem to be necessary any more, as the bug reported in #15071 that was fixed by that commit can't be reproduce any longer in the current version and this commit resulted in other bugs, notably #24042 and probably also #24063. --- src/aui/auibook.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 035e763edb..1651cabb43 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -2726,10 +2726,7 @@ void wxAuiNotebook::OnTabEndDrag(wxAuiNotebookEvent& evt) wxPoint mouse_screen_pt = ::wxGetMousePosition(); wxPoint mouse_client_pt = ScreenToClient(mouse_screen_pt); - // Update our selection (it may be updated again below but the code below - // can also return without doing anything else and this ensures that the - // selection is updated even then). - m_curPage = src_tabs->GetActivePage(); + // check for an external move if (m_flags & wxAUI_NB_TAB_EXTERNAL_MOVE) From f33049028707176fbde023ce5531d2dc74128578 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 15:32:02 +0100 Subject: [PATCH 084/257] Document that wxAUI_MGR_RECTANGLE_HINT shouldn't be used It doesn't work under wxGTK and wxOSX because wxScreenDC can't be used there. --- interface/wx/aui/framemanager.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/wx/aui/framemanager.h b/interface/wx/aui/framemanager.h index 359aecfc04..26a5fbd94c 100644 --- a/interface/wx/aui/framemanager.h +++ b/interface/wx/aui/framemanager.h @@ -134,7 +134,9 @@ enum wxAuiManagerOption appearing partially transparent hint. @style{wxAUI_MGR_RECTANGLE_HINT} The possible location for docking is indicated by a rectangular - outline. + outline. Note that this flag doesn't work, i.e. doesn't show any + hint in wxGTK and wxOSX, please use one of the hint flags above + instead. @style{wxAUI_MGR_HINT_FADE} The translucent area where the pane could be docked appears gradually. @style{wxAUI_MGR_NO_VENETIAN_BLINDS_FADE} From f79b9d01c5980500fe6b7ceefbe122d6f9a7d0cd Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 15:47:03 +0100 Subject: [PATCH 085/257] Make wxAUI hint window highlight colour more noticeable This makes the hint much more visible under wxGTK where the previously used wxSYS_COLOUR_ACTIVECAPTION was typically too light in the default light mode and almost completely invisible in dark mode. Under wxMSW appearance in dark mode is also improved, although the hint is still not very visible there -- but this is still better than being completely invisible before. Closes #23987. --- src/aui/framemanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index aa2e448e9f..e84c43005b 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -852,7 +852,7 @@ void wxAuiManager::UpdateHintWindowConfig() wxFRAME_NO_TASKBAR | wxNO_BORDER); - m_hintWnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_ACTIVECAPTION)); + m_hintWnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HOTLIGHT)); #elif defined(__WXMAC__) // Using a miniframe with float and tool styles keeps the parent // frame activated and highlighted as such... From e8a6f3b732009b999eba3636e1e9baa58fb1721a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 15:55:40 +0100 Subject: [PATCH 086/257] Use wxSYS_COLOUR_HOTLIGHT for hint background under Mac too This works nicely in both light and dark mode and is better than just hard-coding wxBLUE. --- src/aui/framemanager.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index e84c43005b..9e5bfe2054 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -852,7 +852,8 @@ void wxAuiManager::UpdateHintWindowConfig() wxFRAME_NO_TASKBAR | wxNO_BORDER); - m_hintWnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HOTLIGHT)); + // We can set the background of the frame itself directly. + auto bgWnd = m_hintWnd; #elif defined(__WXMAC__) // Using a miniframe with float and tool styles keeps the parent // frame activated and highlighted as such... @@ -863,15 +864,10 @@ void wxAuiManager::UpdateHintWindowConfig() m_hintWnd->Bind(wxEVT_ACTIVATE, &wxAuiManager::OnHintActivate, this); // Can't set the bg colour of a Frame in wxMac - wxPanel* p = new wxPanel(m_hintWnd); - - // The default wxSYS_COLOUR_ACTIVECAPTION colour is a light silver - // color that is really hard to see, especially transparent. - // Until a better system color is decided upon we'll just use - // blue. - p->SetBackgroundColour(*wxBLUE); + wxPanel* bgWnd = new wxPanel(m_hintWnd); #endif + bgWnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HOTLIGHT)); } else { From 787fd9814263396d8658762f6712bbf148921c7e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 16:08:17 +0100 Subject: [PATCH 087/257] Remove unnecessary dynamic cast to wxPseudoTransparentFrame Just test whether we're using "Venetian blinds" hint directly instead of testing for whether we use wxPseudoTransparentFrame which can be also used for the default transparent hint if transparency is not supported natively. This doesn't change much in practice, but just avoid using dynamic cast unnecessarily. --- src/aui/framemanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 9e5bfe2054..b56e29da08 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -3314,7 +3314,7 @@ void wxAuiManager::ShowHint(const wxRect& rect) m_hintFadeAmt = m_hintFadeMax; if ((m_flags & wxAUI_MGR_HINT_FADE) - && !((wxDynamicCast(m_hintWnd, wxPseudoTransparentFrame)) && + && !((m_flags & wxAUI_MGR_VENETIAN_BLINDS_HINT) && (m_flags & wxAUI_MGR_NO_VENETIAN_BLINDS_FADE)) ) m_hintFadeAmt = 0; From 48982e5aa4ad3c341a2eafdeed81ec87e5967257 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 16:14:15 +0100 Subject: [PATCH 088/257] Initialize m_hintFadeAmt in a more logical way No changes, just don't make the code a bit more clear. --- src/aui/framemanager.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index b56e29da08..b7f7f37a0f 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -3311,13 +3311,15 @@ void wxAuiManager::ShowHint(const wxRect& rect) return; m_lastHint = rect; - m_hintFadeAmt = m_hintFadeMax; - + // Decide if we want to fade in the hint and set it to the end value if + // we don't. if ((m_flags & wxAUI_MGR_HINT_FADE) && !((m_flags & wxAUI_MGR_VENETIAN_BLINDS_HINT) && (m_flags & wxAUI_MGR_NO_VENETIAN_BLINDS_FADE)) ) m_hintFadeAmt = 0; + else + m_hintFadeAmt = m_hintFadeMax; m_hintWnd->SetSize(rect); m_hintWnd->SetTransparent(m_hintFadeAmt); From 219f8908b5e4f0bcc75a2a245dc4a554717186a2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 16:18:18 +0100 Subject: [PATCH 089/257] Make hint window fade in animation actually noticeable Using 5ms delay for the fade in timer and 4 point increment for the value running from 0 to 50 meant that the entire fade in took 60ms which wasn't really noticeable, i.e. couldn't be distinguished from not using fade in at all. Increase the delay to 15ms (which corresponds to ~60 FPS) and make the animation last longer by increasing the transparency more progressively to make the fade in actually visible. In the future we probably ought to make all the values involved (animation duration, initial and end values and the step) configurable by adding some SetHintFadeInOptions() to wxAuiManager. --- src/aui/framemanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index b7f7f37a0f..528f8dcf3c 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -3298,7 +3298,7 @@ void wxAuiManager::OnHintFadeTimer(wxTimerEvent& WXUNUSED(event)) return; } - m_hintFadeAmt += 4; + m_hintFadeAmt++; m_hintWnd->SetTransparent(m_hintFadeAmt); } @@ -3339,7 +3339,7 @@ void wxAuiManager::ShowHint(const wxRect& rect) { // start fade in timer m_hintFadeTimer.SetOwner(this); - m_hintFadeTimer.Start(5); + m_hintFadeTimer.Start(15); Bind(wxEVT_TIMER, &wxAuiManager::OnHintFadeTimer, this, m_hintFadeTimer.GetId()); } From e4bce8f8917235f1566d4a37e684e014fa51d774 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 16:36:54 +0100 Subject: [PATCH 090/257] Simplify platform test when creating hint window Instead of checking for all the other platforms, just check for non-Mac as the code in this branch should work (and definitely should compile) in any port and it's just wxOSX which requires special handling here. This fixes the build under the other platforms (e.g. wxX11) broken by the changes of e8a6f3b732 (Use wxSYS_COLOUR_HOTLIGHT for hint background under Mac too, 2023-12-24). --- src/aui/framemanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 528f8dcf3c..be5fc5e0b2 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -844,7 +844,7 @@ void wxAuiManager::UpdateHintWindowConfig() if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) && can_do_transparent) { // Make a window to use for a transparent hint - #if defined(__WXMSW__) || defined(__WXGTK__) || defined(__WXQT__) + #ifndef __WXMAC__ m_hintWnd = new wxFrame(m_frame, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(1,1), wxFRAME_TOOL_WINDOW | @@ -854,7 +854,7 @@ void wxAuiManager::UpdateHintWindowConfig() // We can set the background of the frame itself directly. auto bgWnd = m_hintWnd; - #elif defined(__WXMAC__) + #else // Mac // Using a miniframe with float and tool styles keeps the parent // frame activated and highlighted as such... m_hintWnd = new wxMiniFrame(m_frame, wxID_ANY, wxEmptyString, From e605649f6389407fb2526338e6c136948dd3140c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 17:15:57 +0100 Subject: [PATCH 091/257] Set hint window background directly under Mac too This does work, contrary to the comment saying that it doesn't: it must have been when cf6fec73d7 (wxaui flags reworked a bit; allows any hinting type to be explicity invoked; turning off hinting completely is not possible; sample updated accordingly, 2006-10-26) was done, but not any longer. No real changes, just simplify the code. --- src/aui/framemanager.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index be5fc5e0b2..0816cd30c4 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -851,9 +851,6 @@ void wxAuiManager::UpdateHintWindowConfig() wxFRAME_FLOAT_ON_PARENT | wxFRAME_NO_TASKBAR | wxNO_BORDER); - - // We can set the background of the frame itself directly. - auto bgWnd = m_hintWnd; #else // Mac // Using a miniframe with float and tool styles keeps the parent // frame activated and highlighted as such... @@ -862,12 +859,9 @@ void wxAuiManager::UpdateHintWindowConfig() wxFRAME_FLOAT_ON_PARENT | wxFRAME_TOOL_WINDOW ); m_hintWnd->Bind(wxEVT_ACTIVATE, &wxAuiManager::OnHintActivate, this); - - // Can't set the bg colour of a Frame in wxMac - wxPanel* bgWnd = new wxPanel(m_hintWnd); #endif - bgWnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HOTLIGHT)); + m_hintWnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HOTLIGHT)); } else { From b1c9ebd7be881acb59a582f5a9dddcca37d1dbcb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 17:19:29 +0100 Subject: [PATCH 092/257] Don't use wxMiniFrame for hint window under Mac wxMiniFrame is the same thing as wxFrame there, so there is no point in using different code path for Mac. No real changes. --- src/aui/framemanager.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 0816cd30c4..133b34eb0c 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -844,20 +844,13 @@ void wxAuiManager::UpdateHintWindowConfig() if ((m_flags & wxAUI_MGR_TRANSPARENT_HINT) && can_do_transparent) { // Make a window to use for a transparent hint - #ifndef __WXMAC__ - m_hintWnd = new wxFrame(m_frame, wxID_ANY, wxEmptyString, - wxDefaultPosition, wxSize(1,1), - wxFRAME_TOOL_WINDOW | - wxFRAME_FLOAT_ON_PARENT | - wxFRAME_NO_TASKBAR | - wxNO_BORDER); - #else // Mac - // Using a miniframe with float and tool styles keeps the parent - // frame activated and highlighted as such... - m_hintWnd = new wxMiniFrame(m_frame, wxID_ANY, wxEmptyString, - wxDefaultPosition, wxSize(1,1), - wxFRAME_FLOAT_ON_PARENT - | wxFRAME_TOOL_WINDOW ); + m_hintWnd = new wxFrame(m_frame, wxID_ANY, wxEmptyString, + wxDefaultPosition, wxSize(1,1), + wxFRAME_TOOL_WINDOW | + wxFRAME_FLOAT_ON_PARENT | + wxFRAME_NO_TASKBAR | + wxNO_BORDER); + #ifdef __WXMAC__ m_hintWnd->Bind(wxEVT_ACTIVATE, &wxAuiManager::OnHintActivate, this); #endif From 45d7ac6d94c35948bf463623b685213ff1848e14 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 17:21:12 +0100 Subject: [PATCH 093/257] Don't define a separate wxAuiManager::OnHintActivate() This was only used under Mac but defined under all platforms. Don't bother with defining it elsewhere and just use a trivial empty lambda as wxEVT_ACTIVATE handler under Mac. Note that it's not really clear if this is still needed neither, but it doesn't cost much to keep this workaround just in case it is. --- include/wx/aui/framemanager.h | 2 -- src/aui/framemanager.cpp | 21 ++++++++------------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/include/wx/aui/framemanager.h b/include/wx/aui/framemanager.h index da9dff9609..61e9ae640a 100644 --- a/include/wx/aui/framemanager.h +++ b/include/wx/aui/framemanager.h @@ -485,8 +485,6 @@ public: virtual void ShowHint(const wxRect& rect); virtual void HideHint(); - void OnHintActivate(wxActivateEvent& event); - public: // deprecated -- please use SetManagedWindow() diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 133b34eb0c..e3ea6a1328 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -851,7 +851,14 @@ void wxAuiManager::UpdateHintWindowConfig() wxFRAME_NO_TASKBAR | wxNO_BORDER); #ifdef __WXMAC__ - m_hintWnd->Bind(wxEVT_ACTIVATE, &wxAuiManager::OnHintActivate, this); + // Do nothing so this event isn't handled in the base handlers. + + // Letting the hint window activate without this handler can lead to + // weird behaviour on Mac where the menu is switched out to the top + // window's menu in MDI applications when it shouldn't be. So since + // we don't want user interaction with the hint window anyway, we just + // prevent it from activating here. + m_hintWnd->Bind(wxEVT_ACTIVATE, [](wxActivateEvent&) {}); #endif m_hintWnd->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_HOTLIGHT)); @@ -3414,18 +3421,6 @@ void wxAuiManager::HideHint() } } -void wxAuiManager::OnHintActivate(wxActivateEvent& WXUNUSED(event)) -{ - // Do nothing so this event isn't handled in the base handlers. - - // Letting the hint window activate without this handler can lead to - // weird behaviour on Mac where the menu is switched out to the top - // window's menu in MDI applications when it shouldn't be. So since - // we don't want user interaction with the hint window anyway, we just - // prevent it from activating here. -} - - void wxAuiManager::StartPaneDrag(wxWindow* pane_window, const wxPoint& offset) From 83707a975d9edf37f3343bf7c32c38cf6b2f9cf1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 14:44:15 +0100 Subject: [PATCH 094/257] Use ProcessEvent() in wxAuiNotebook code No real changes, just replace GetEventHandler()->ProcessEvent() with the calls to this function, which does exactly the same thing, but is shorter and more clear. --- src/aui/auibook.cpp | 60 ++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 035e763edb..5931186b1b 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -1081,7 +1081,7 @@ void wxAuiTabCtrl::OnLeftDown(wxMouseEvent& evt) e.SetSelection(new_selection); e.SetOldSelection(GetActivePage()); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } m_clickPt.x = evt.m_x; @@ -1110,7 +1110,7 @@ void wxAuiTabCtrl::OnCaptureLost(wxMouseCaptureLostEvent& WXUNUSED(event)) evt.SetSelection(GetIdxFromWindow(clickTab)); evt.SetOldSelection(evt.GetSelection()); evt.SetEventObject(this); - GetEventHandler()->ProcessEvent(evt); + ProcessWindowEvent(evt); } } @@ -1129,7 +1129,7 @@ void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt) e.SetSelection(GetIdxFromWindow(clickTab)); e.SetOldSelection(e.GetSelection()); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); return; } @@ -1157,7 +1157,7 @@ void wxAuiTabCtrl::OnLeftUp(wxMouseEvent& evt) e.SetSelection(GetIdxFromWindow(m_clickTab)); e.SetInt(m_pressedButton->id); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } m_pressedButton = nullptr; @@ -1175,7 +1175,7 @@ void wxAuiTabCtrl::OnMiddleUp(wxMouseEvent& evt) wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_TAB_MIDDLE_UP, m_windowId); e.SetEventObject(this); e.SetSelection(GetIdxFromWindow(wnd)); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } void wxAuiTabCtrl::OnMiddleDown(wxMouseEvent& evt) @@ -1187,7 +1187,7 @@ void wxAuiTabCtrl::OnMiddleDown(wxMouseEvent& evt) wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_TAB_MIDDLE_DOWN, m_windowId); e.SetEventObject(this); e.SetSelection(GetIdxFromWindow(wnd)); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } void wxAuiTabCtrl::OnRightUp(wxMouseEvent& evt) @@ -1199,7 +1199,7 @@ void wxAuiTabCtrl::OnRightUp(wxMouseEvent& evt) wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_TAB_RIGHT_UP, m_windowId); e.SetEventObject(this); e.SetSelection(GetIdxFromWindow(wnd)); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } void wxAuiTabCtrl::OnRightDown(wxMouseEvent& evt) @@ -1211,7 +1211,7 @@ void wxAuiTabCtrl::OnRightDown(wxMouseEvent& evt) wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_TAB_RIGHT_DOWN, m_windowId); e.SetEventObject(this); e.SetSelection(GetIdxFromWindow(wnd)); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } void wxAuiTabCtrl::OnLeftDClick(wxMouseEvent& evt) @@ -1222,7 +1222,7 @@ void wxAuiTabCtrl::OnLeftDClick(wxMouseEvent& evt) { wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_BG_DCLICK, m_windowId); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } } @@ -1295,7 +1295,7 @@ void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt) e.SetSelection(GetIdxFromWindow(m_clickTab)); e.SetOldSelection(e.GetSelection()); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); return; } @@ -1310,7 +1310,7 @@ void wxAuiTabCtrl::OnMotion(wxMouseEvent& evt) e.SetSelection(GetIdxFromWindow(m_clickTab)); e.SetOldSelection(e.GetSelection()); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); m_isDragging = true; } @@ -1361,7 +1361,7 @@ void wxAuiTabCtrl::OnButton(wxAuiNotebookEvent& event) e.SetSelection(idx); e.SetOldSelection(GetActivePage()); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } } else @@ -1437,7 +1437,7 @@ void wxAuiTabCtrl::OnChar(wxKeyEvent& event) keyEvent.SetFromTab(bFromTab); keyEvent.SetEventObject(nb); - if (!nb->GetEventHandler()->ProcessEvent(keyEvent)) + if (!nb->ProcessWindowEvent(keyEvent)) { // Not processed? Do an explicit tab into the page. wxWindow* win = GetWindowFromIdx(GetActivePage()); @@ -1504,7 +1504,7 @@ void wxAuiTabCtrl::OnChar(wxKeyEvent& event) e.SetSelection(newPage); e.SetOldSelection(newPage); e.SetEventObject(this); - this->GetEventHandler()->ProcessEvent(e); + this->ProcessWindowEvent(e); } else event.Skip(); @@ -2311,7 +2311,7 @@ void wxAuiNotebook::SetSelectionToWindow(wxWindow *win) if (parent) { wxChildFocusEvent eventFocus(this); - parent->GetEventHandler()->ProcessEvent(eventFocus); + parent->ProcessWindowEvent(eventFocus); } @@ -2570,7 +2570,7 @@ void wxAuiNotebook::OnTabBgDClick(wxAuiNotebookEvent& evt) // notify owner that the tabbar background has been double-clicked wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_BG_DCLICK, m_windowId); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } void wxAuiNotebook::OnTabBeginDrag(wxAuiNotebookEvent&) @@ -2758,7 +2758,7 @@ void wxAuiNotebook::OnTabEndDrag(wxAuiNotebookEvent& evt) e.SetDragSource(this); e.Veto(); // dropping must be explicitly approved by control owner - nb->GetEventHandler()->ProcessEvent(e); + nb->ProcessWindowEvent(e); if (!e.IsAllowed()) { @@ -2829,7 +2829,7 @@ void wxAuiNotebook::OnTabEndDrag(wxAuiNotebookEvent& evt) e2.SetSelection(evt.GetSelection()); e2.SetOldSelection(evt.GetSelection()); e2.SetEventObject(this); - GetEventHandler()->ProcessEvent(e2); + ProcessWindowEvent(e2); return; } @@ -2940,7 +2940,7 @@ void wxAuiNotebook::OnTabEndDrag(wxAuiNotebookEvent& evt) e.SetSelection(evt.GetSelection()); e.SetOldSelection(evt.GetSelection()); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } @@ -3139,7 +3139,7 @@ void wxAuiNotebook::OnNavigationKeyNotebook(wxNavigationKeyEvent& event) event.SetEventObject(this); wxWindow *page = GetPage(GetSelection()); - if ( !page->GetEventHandler()->ProcessEvent(event) ) + if ( !page->ProcessWindowEvent(event) ) { page->SetFocus(); } @@ -3163,7 +3163,7 @@ void wxAuiNotebook::OnNavigationKeyNotebook(wxNavigationKeyEvent& event) else if ( parent ) { event.SetCurrentFocus(this); - parent->GetEventHandler()->ProcessEvent(event); + parent->ProcessWindowEvent(event); } } } @@ -3197,7 +3197,7 @@ void wxAuiNotebook::OnTabButton(wxAuiNotebookEvent& evt) e.SetSelection(idx); e.SetOldSelection(evt.GetSelection()); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); if (!e.IsAllowed()) return; @@ -3220,7 +3220,7 @@ void wxAuiNotebook::OnTabButton(wxAuiNotebookEvent& evt) wxAuiNotebookEvent e2(wxEVT_AUINOTEBOOK_PAGE_CLOSED, m_windowId); e2.SetSelection(idx); e2.SetEventObject(this); - GetEventHandler()->ProcessEvent(e2); + ProcessWindowEvent(e2); } } } @@ -3235,7 +3235,7 @@ void wxAuiNotebook::OnTabMiddleDown(wxAuiNotebookEvent& evt) wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_TAB_MIDDLE_DOWN, m_windowId); e.SetSelection(m_tabs.GetIdxFromWindow(wnd)); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } void wxAuiNotebook::OnTabMiddleUp(wxAuiNotebookEvent& evt) @@ -3251,7 +3251,7 @@ void wxAuiNotebook::OnTabMiddleUp(wxAuiNotebookEvent& evt) wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_TAB_MIDDLE_UP, m_windowId); e.SetSelection(m_tabs.GetIdxFromWindow(wnd)); e.SetEventObject(this); - if (GetEventHandler()->ProcessEvent(e)) + if (ProcessWindowEvent(e)) return; if (!e.IsAllowed()) return; @@ -3274,7 +3274,7 @@ void wxAuiNotebook::OnTabRightDown(wxAuiNotebookEvent& evt) wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_TAB_RIGHT_DOWN, m_windowId); e.SetSelection(m_tabs.GetIdxFromWindow(wnd)); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } void wxAuiNotebook::OnTabRightUp(wxAuiNotebookEvent& evt) @@ -3286,7 +3286,7 @@ void wxAuiNotebook::OnTabRightUp(wxAuiNotebookEvent& evt) wxAuiNotebookEvent e(wxEVT_AUINOTEBOOK_TAB_RIGHT_UP, m_windowId); e.SetSelection(m_tabs.GetIdxFromWindow(wnd)); e.SetEventObject(this); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); } // Sets the normal font @@ -3354,7 +3354,7 @@ bool wxAuiNotebook::ShowWindowMenu() e.SetSelection(idx); e.SetOldSelection(tabCtrl->GetActivePage()); e.SetEventObject(tabCtrl); - GetEventHandler()->ProcessEvent(e); + ProcessWindowEvent(e); return true; } @@ -3632,7 +3632,7 @@ int wxAuiNotebook::DoModifySelection(size_t n, bool events) evt.SetSelection(n); evt.SetOldSelection(m_curPage); evt.SetEventObject(this); - GetEventHandler()->ProcessEvent(evt); + ProcessWindowEvent(evt); vetoed = !evt.IsAllowed(); } @@ -3678,7 +3678,7 @@ int wxAuiNotebook::DoModifySelection(size_t n, bool events) if(events) { evt.SetEventType(wxEVT_AUINOTEBOOK_PAGE_CHANGED); - (void)GetEventHandler()->ProcessEvent(evt); + (void)ProcessWindowEvent(evt); } return old_curpage; From 18bba7b70be1f225009931937a8a52d342308593 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 15:01:15 +0100 Subject: [PATCH 095/257] Document correct way of handling wxAuiNotebookEvents They need to be handled at wxAuiNotebook level as they are all processed there and don't propagate up to the parent. Closes #24118. --- interface/wx/aui/auibook.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/interface/wx/aui/auibook.h b/interface/wx/aui/auibook.h index c8d6510f78..d00f54140e 100644 --- a/interface/wx/aui/auibook.h +++ b/interface/wx/aui/auibook.h @@ -114,6 +114,9 @@ enum wxAuiNotebookOption Double clicked on the tabs background area. Processes a @c wxEVT_AUINOTEBOOK_BG_DCLICK event. @endEventTable + Please see the note in wxAuiNotebookEvent documentation about handling + these events. + @library{wxaui} @category{aui} */ @@ -712,6 +715,13 @@ public: This class is used by the events generated by wxAuiNotebook. + Please note that most events generated by wxAuiNotebook are handled by the + notebook object itself, i.e. they do _not_ propagate upwards to the + notebook parent window, in spite of being command events. In order to + handle these events you should use wxEvtHandler::Bind() to connect to the + events on the notebook object itself and don't forget to use + wxEvent::Skip() to ensure that the notebook still processes them too. + @beginEventEmissionTable{wxAuiNotebookEvent} @event{EVT_AUINOTEBOOK_PAGE_CLOSE(id, func)} A page is about to be closed. Processes a @c wxEVT_AUINOTEBOOK_PAGE_CLOSE event. From c8552aec0c1405a2461dcdd65788a7090d65a5ab Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 23 Dec 2023 18:45:57 +0100 Subject: [PATCH 096/257] Make wxPGPropertyFlags a bitmask To improve type safety of flags. --- include/wx/propgrid/advprops.h | 4 +- include/wx/propgrid/private.h | 22 +- include/wx/propgrid/property.h | 414 +++++++++++++++------- include/wx/propgrid/propgrid.h | 8 +- include/wx/propgrid/propgridiface.h | 28 +- include/wx/propgrid/propgridpagestate.h | 64 ++-- include/wx/propgrid/props.h | 12 +- interface/wx/propgrid/property.h | 296 ++++++++-------- interface/wx/propgrid/propgrid.h | 9 +- interface/wx/propgrid/propgridiface.h | 2 +- interface/wx/propgrid/propgridpagestate.h | 47 ++- src/propgrid/advprops.cpp | 42 +-- src/propgrid/editors.cpp | 36 +- src/propgrid/property.cpp | 130 ++++--- src/propgrid/propgrid.cpp | 56 +-- src/propgrid/propgridiface.cpp | 36 +- src/propgrid/propgridpagestate.cpp | 24 +- src/propgrid/props.cpp | 58 +-- tests/controls/propgridtest.cpp | 90 ++--- 19 files changed, 763 insertions(+), 615 deletions(-) diff --git a/include/wx/propgrid/advprops.h b/include/wx/propgrid/advprops.h index 7ae62397d1..f5375997be 100644 --- a/include/wx/propgrid/advprops.h +++ b/include/wx/propgrid/advprops.h @@ -150,8 +150,8 @@ protected: #if WXWIN_COMPATIBILITY_3_2 // If set, then match from list is searched for a custom colour. -wxDEPRECATED_BUT_USED_INTERNALLY_MSG("wxPG_PROP_TRANSLATE_CUSTOM is intended for internal use.") -constexpr wxPGPropertyFlags wxPG_PROP_TRANSLATE_CUSTOM = wxPG_PROP_RESERVED_1; +wxDEPRECATED_MSG("wxPG_PROP_TRANSLATE_CUSTOM is intended for internal use.") +constexpr wxPGPropertyFlags wxPG_PROP_TRANSLATE_CUSTOM = wxPGPropertyFlags::Reserved_1; #endif // WXWIN_COMPATIBILITY_3_2 // Has dropdown list of wxWidgets system colours. Value used is diff --git a/include/wx/propgrid/private.h b/include/wx/propgrid/private.h index 67f17edbd5..72c3ca23f9 100644 --- a/include/wx/propgrid/private.h +++ b/include/wx/propgrid/private.h @@ -188,31 +188,29 @@ wxDECLARE_EVENT(wxEVT_PG_COLS_RESIZED, wxPropertyGridEvent); // Flags used only internally // wxBoolProperty, wxFlagsProperty specific flags -constexpr wxPGPropertyFlags wxPG_PROP_USE_CHECKBOX = wxPG_PROP_RESERVED_1; +constexpr wxPGPropertyFlags wxPGPropertyFlags_UseCheckBox = wxPGPropertyFlags::Reserved_1; // DCC = Double Click Cycles -constexpr wxPGPropertyFlags wxPG_PROP_USE_DCC = wxPG_PROP_RESERVED_2; +constexpr wxPGPropertyFlags wxPGPropertyFlags_UseDCC = wxPGPropertyFlags::Reserved_2; // wxStringProperty flag -constexpr wxPGPropertyFlags wxPG_PROP_PASSWORD = wxPG_PROP_RESERVED_2; +constexpr wxPGPropertyFlags wxPGPropertyFlags_Password = wxPGPropertyFlags::Reserved_2; -#if !WXWIN_COMPATIBILITY_3_2 // wxColourProperty flag - if set, then match from list is searched for a custom colour. -constexpr wxPGPropertyFlags wxPG_PROP_TRANSLATE_CUSTOM = wxPG_PROP_RESERVED_1; +constexpr wxPGPropertyFlags wxPGPropertyFlags_TranslateCustom = wxPGPropertyFlags::Reserved_1; // wxCursorProperty, wxSystemColourProperty - If set, then selection of choices is static // and should not be changed (i.e. returns nullptr in GetPropertyChoices). -constexpr wxPGPropertyFlags wxPG_PROP_STATIC_CHOICES = wxPG_PROP_RESERVED_1; +constexpr wxPGPropertyFlags wxPGPropertyFlags_StaticChoices = wxPGPropertyFlags::Reserved_1; -// wxSystemColourProperty - wxEnumProperty based classes cannot use wxPG_PROP_RESERVED_1 -constexpr wxPGPropertyFlags wxPG_PROP_HIDE_CUSTOM_COLOUR = wxPG_PROP_RESERVED_2; -constexpr wxPGPropertyFlags wxPG_PROP_COLOUR_HAS_ALPHA = wxPG_PROP_RESERVED_3; +// wxSystemColourProperty - wxEnumProperty based classes cannot use wxPGPropertyFlags::Reserved_1 +constexpr wxPGPropertyFlags wxPGPropertyFlags_HideCustomColour = wxPGPropertyFlags::Reserved_2; +constexpr wxPGPropertyFlags wxPGPropertyFlags_ColourHasAlpha = wxPGPropertyFlags::Reserved_3; // wxFileProperty - if set, full path is shown in wxFileProperty. -constexpr wxPGPropertyFlags wxPG_PROP_SHOW_FULL_FILENAME = wxPG_PROP_RESERVED_1; +constexpr wxPGPropertyFlags wxPGPropertyFlags_ShowFullFileName = wxPGPropertyFlags::Reserved_1; // wxLongStringProperty - flag used to mark that edit button // should be enabled even in the read-only mode. -constexpr wxPGPropertyFlags wxPG_PROP_ACTIVE_BTN = wxPG_PROP_RESERVED_3; -#endif // !WXWIN_COMPATIBILITY_3_2 +constexpr wxPGPropertyFlags wxPGPropertyFlags_ActiveButton = wxPGPropertyFlags::Reserved_3; #endif // _WX_PROPGRID_PRIVATE_H_ diff --git a/include/wx/propgrid/property.h b/include/wx/propgrid/property.h index 5cfd6f7118..076a0cc58e 100644 --- a/include/wx/propgrid/property.h +++ b/include/wx/propgrid/property.h @@ -304,129 +304,229 @@ protected: std::unordered_map m_map; }; - -// ----------------------------------------------------------------------- - -enum wxPGPropertyFlags +enum class wxPGPropertyFlags : int { + // No flags. + Null = 0, -// Indicates bold font. -wxPG_PROP_MODIFIED = 0x0001, + // Indicates bold font. + Modified = 0x0001, -// Disables ('greyed' text and editor does not activate) property. -wxPG_PROP_DISABLED = 0x0002, + // Disables ('greyed' text and editor does not activate) property. + Disabled = 0x0002, -// Hider button will hide this property. -wxPG_PROP_HIDDEN = 0x0004, + // Hider button will hide this property. + Hidden = 0x0004, -// This property has custom paint image just in front of its value. -// If property only draws custom images into a popup list, then this -// flag should not be set. -wxPG_PROP_CUSTOMIMAGE = 0x0008, + // This property has custom paint image just in front of its value. + // If property only draws custom images into a popup list, then this + // flag should not be set. + CustomImage = 0x0008, -// Do not create text based editor for this property (but button-triggered -// dialog and choice are ok). -wxPG_PROP_NOEDITOR = 0x0010, + // Do not create text based editor for this property (but button-triggered + // dialog and choice are ok). + NoEditor = 0x0010, -// Property is collapsed, ie. its children are hidden. -wxPG_PROP_COLLAPSED = 0x0020, + // Property is collapsed, ie. it's children are hidden. + Collapsed = 0x0020, -// If property is selected, then indicates that validation failed for pending -// value. -// If property is not selected, that indicates that the actual property -// value has failed validation (NB: this behaviour is not currently supported, -// but may be used in future). -wxPG_PROP_INVALID_VALUE = 0x0040, + // If property is selected, then indicates that validation failed for pending + // value. + // If property is not selected, that indicates that the actual property + // value has failed validation (NB: this behaviour is not currently supported, + // but may be used in future). + InvalidValue = 0x0040, -// 0x0080, + // 0x0080, -// Switched via SetWasModified(). Temporary flag - only used when -// setting/changing property value. -wxPG_PROP_WAS_MODIFIED = 0x0200, + // Switched via SetWasModified(). Temporary flag - only used when + // setting/changing property value. + WasModified = 0x0200, -// If set, then child properties (if any) are private, and should be -// "invisible" to the application. -wxPG_PROP_AGGREGATE = 0x0400, + // If set, then child properties (if any) are private, and should be + // "invisible" to the application. + Aggregate = 0x0400, -// If set, then child properties (if any) are copies and should not -// be deleted in dtor. -wxPG_PROP_CHILDREN_ARE_COPIES = 0x0800, + // If set, then child properties (if any) are copies and should not + // be deleted in dtor. + ChildrenAreCopies = 0x0800, -// Classifies this item as a non-category. -// Used for faster item type identification. -wxPG_PROP_PROPERTY = 0x1000, + // Classifies this item as a non-category. + // Used for faster item type identification. + Property = 0x1000, -// Classifies this item as a category. -// Used for faster item type identification. -wxPG_PROP_CATEGORY = 0x2000, + // Classifies this item as a category. + // Used for faster item type identification. + Category = 0x2000, -// Classifies this item as a property that has children, -//but is not aggregate (i.e. children are not private). -wxPG_PROP_MISC_PARENT = 0x4000, + // Classifies this item as a property that has children, + //but is not aggregate (i.e. children are not private). + MiscParent = 0x4000, -// Property is read-only. Editor is still created for wxTextCtrl-based -// property editors. For others, editor is not usually created because -// they do implement wxTE_READONLY style or equivalent. -wxPG_PROP_READONLY = 0x8000, + // Property is read-only. Editor is still created for wxTextCtrl-based + // property editors. For others, editor is not usually created because + // they do implement wxTE_READONLY style or equivalent. + ReadOnly = 0x8000, -// -// NB: FLAGS ABOVE 0x8000 CANNOT BE USED WITH PROPERTY ITERATORS -// + // + // NB: FLAGS ABOVE 0x8000 CANNOT BE USED WITH PROPERTY ITERATORS + // -// Property's value is composed from values of child properties. -// This flag cannot be used with property iterators. -wxPG_PROP_COMPOSED_VALUE = 0x00010000, + // Property's value is composed from values of child properties. + // This flag cannot be used with property iterators. + ComposedValue = 0x00010000, -// Common value of property is selectable in editor. -// This flag cannot be used with property iterators. -wxPG_PROP_USES_COMMON_VALUE = 0x00020000, + // Common value of property is selectable in editor. + // This flag cannot be used with property iterators. + UsesCommonValue = 0x00020000, -// Property can be set to unspecified value via editor. -// Currently, this applies to following properties: -// - wxIntProperty, wxUIntProperty, wxFloatProperty, wxEditEnumProperty: -// Clear the text field -// This flag cannot be used with property iterators. -// See wxPGProperty::SetAutoUnspecified(). -wxPG_PROP_AUTO_UNSPECIFIED = 0x00040000, + // Property can be set to unspecified value via editor. + // Currently, this applxPGies to following properties: + // - wxIntProperty, wxUIntProperty, wxFloatProperty, wxEditEnumProperty: + // Clear the text field + // This flag cannot be used with property iterators. + // See wxPGProperty::SetAutoUnspecified(). + AutoUnspecified = 0x00040000, -// For internal use only. -wxPG_PROP_RESERVED_1 = 0x00080000, + // Indicates that the property is being deleted and should be ignored. + BeingDeleted = 0x00080000, -// For internal use only. -wxPG_PROP_RESERVED_2 = 0x00100000, + // If set, full path is shown in wxFileProperty. + ShowFullFileName = 0x00100000, -// Indicates that the property is being deleted and should be ignored. -wxPG_PROP_BEING_DELETED = 0x00200000, + // For internal use only. + Reserved_1 = 0x10000000, -// For internal use only. -wxPG_PROP_RESERVED_3 = 0x00400000 + // For internal use only. + Reserved_2 = 0x20000000, + + // For internal use only. + Reserved_3 = 0x40000000, + + // Topmost flag. + Max = ShowFullFileName, + + // Property with children must have one of these set, otherwise iterators + // will not work correctly. + // Code should automatically take care of this, however. + ParentalFlags = Aggregate | Category | MiscParent, + + // Combination of flags that can be stored by GetFlagsAsString + StringStoredFlags = Disabled | Hidden | NoEditor | Collapsed }; +constexpr wxPGPropertyFlags operator|(wxPGPropertyFlags a, wxPGPropertyFlags b) +{ + return static_cast(static_cast(a) | static_cast(b)); +} + +inline wxPGPropertyFlags operator|=(wxPGPropertyFlags & a, wxPGPropertyFlags b) +{ + return a = a | b; +} + +constexpr wxPGPropertyFlags operator&(wxPGPropertyFlags a, wxPGPropertyFlags b) +{ + return static_cast(static_cast(a) & static_cast(b)); +} + +inline wxPGPropertyFlags operator&=(wxPGPropertyFlags & a, wxPGPropertyFlags b) +{ + return a = a & b; +} + +constexpr wxPGPropertyFlags operator^(wxPGPropertyFlags a, wxPGPropertyFlags b) +{ + return static_cast(static_cast(a) ^ static_cast(b)); +} + +constexpr wxPGPropertyFlags operator~(wxPGPropertyFlags a) +{ + return static_cast(~static_cast(a)); +} + +constexpr bool operator!(wxPGPropertyFlags a) +{ + return static_cast(a) == 0; +} + +// We need these operators with int arguments for interoperability +// with wxPG_ITERATOR_FLAGS as plain enumeration). +// ===== +constexpr int operator<<(wxPGPropertyFlags a, int n) +{ + return static_cast(a) << n; +} + +constexpr int operator|(wxPGPropertyFlags a, int b) +{ + return static_cast(a) | b; +} + +constexpr int operator|(int a, wxPGPropertyFlags b) +{ + return a | static_cast(b); +} + +constexpr int operator&(int a, wxPGPropertyFlags b) +{ + return a & static_cast(b); +} +// ===== + #if WXWIN_COMPATIBILITY_3_2 +wxDEPRECATED_MSG("use wxPGPropertyFlags::Modified instead") +constexpr wxPGPropertyFlags wxPG_PROP_MODIFIED = wxPGPropertyFlags::Modified; +wxDEPRECATED_MSG("use wxPGPropertyFlags::Disabled instead") +constexpr wxPGPropertyFlags wxPG_PROP_DISABLED = wxPGPropertyFlags::Disabled; +wxDEPRECATED_MSG("use wxPGPropertyFlags::Hidden instead") +constexpr wxPGPropertyFlags wxPG_PROP_HIDDEN = wxPGPropertyFlags::Hidden; +wxDEPRECATED_MSG("use wxPGPropertyFlags::CustomImage instead") +constexpr wxPGPropertyFlags wxPG_PROP_CUSTOMIMAGE = wxPGPropertyFlags::CustomImage; +wxDEPRECATED_MSG("use wxPGPropertyFlags::NoEditor instead") +constexpr wxPGPropertyFlags wxPG_PROP_NOEDITOR = wxPGPropertyFlags::NoEditor; +wxDEPRECATED_MSG("use wxPGPropertyFlags::Collapsed instead") +constexpr wxPGPropertyFlags wxPG_PROP_COLLAPSED = wxPGPropertyFlags::Collapsed; +wxDEPRECATED_MSG("use wxPGPropertyFlags::InvalidValue instead") +constexpr wxPGPropertyFlags wxPG_PROP_INVALID_VALUE = wxPGPropertyFlags::InvalidValue; +wxDEPRECATED_MSG("use wxPGPropertyFlags::WasModified instead") +constexpr wxPGPropertyFlags wxPG_PROP_WAS_MODIFIED = wxPGPropertyFlags::WasModified; +wxDEPRECATED_MSG("use wxPGPropertyFlags::Aggregate instead") +constexpr wxPGPropertyFlags wxPG_PROP_AGGREGATE = wxPGPropertyFlags::Aggregate; +wxDEPRECATED_MSG("use wxPGPropertyFlags::ChildrenAreCopies instead") +constexpr wxPGPropertyFlags wxPG_PROP_CHILDREN_ARE_COPIES = wxPGPropertyFlags::ChildrenAreCopies; +wxDEPRECATED_MSG("use wxPGPropertyFlags::Property instead") +constexpr wxPGPropertyFlags wxPG_PROP_PROPERTY = wxPGPropertyFlags::Property; +wxDEPRECATED_MSG("use wxPGPropertyFlags::Category instead") +constexpr wxPGPropertyFlags wxPG_PROP_CATEGORY = wxPGPropertyFlags::Category; +wxDEPRECATED_MSG("use wxPGPropertyFlags::MiscParent instead") +constexpr wxPGPropertyFlags wxPG_PROP_MISC_PARENT = wxPGPropertyFlags::MiscParent; +wxDEPRECATED_MSG("use wxPGPropertyFlags::ReadOnly instead") +constexpr wxPGPropertyFlags wxPG_PROP_READONLY = wxPGPropertyFlags::ReadOnly; +wxDEPRECATED_MSG("use wxPGPropertyFlags::ComposedValue instead") +constexpr wxPGPropertyFlags wxPG_PROP_COMPOSED_VALUE = wxPGPropertyFlags::ComposedValue; +wxDEPRECATED_MSG("use wxPGPropertyFlags::UsesCommonValue instead") +constexpr wxPGPropertyFlags wxPG_PROP_USES_COMMON_VALUE = wxPGPropertyFlags::UsesCommonValue; +wxDEPRECATED_MSG("use wxPGPropertyFlags::AutoUnspecified instead") +constexpr wxPGPropertyFlags wxPG_PROP_AUTO_UNSPECIFIED = wxPGPropertyFlags::AutoUnspecified; +wxDEPRECATED_MSG("use wxPGPropertyFlags::BeingDeleted instead") +constexpr wxPGPropertyFlags wxPG_PROP_BEING_DELETED = wxPGPropertyFlags::BeingDeleted; +wxDEPRECATED_MSG("use wxPGPropertyFlags::ParentalFlags instead") +constexpr wxPGPropertyFlags wxPG_PROP_PARENTAL_FLAGS = wxPGPropertyFlags::ParentalFlags; +wxDEPRECATED_MSG("use wxPGPropertyFlags::StringStoredFlags instead") +constexpr wxPGPropertyFlags wxPG_STRING_STORED_FLAGS = wxPGPropertyFlags::StringStoredFlags; +wxDEPRECATED_MSG("use wxPGPropertyFlags::Max instead") +constexpr wxPGPropertyFlags wxPG_PROP_MAX = wxPGPropertyFlags::Max; + // Indicates bits usable by derived properties. wxDEPRECATED_BUT_USED_INTERNALLY_MSG("wxPG_PROP_CLASS_SPECIFIC_1 in intended for internal use only.") -constexpr wxPGPropertyFlags wxPG_PROP_CLASS_SPECIFIC_1 = wxPG_PROP_RESERVED_1; +constexpr wxPGPropertyFlags wxPG_PROP_CLASS_SPECIFIC_1 = wxPGPropertyFlags::Reserved_1; wxDEPRECATED_BUT_USED_INTERNALLY_MSG("wxPG_PROP_CLASS_SPECIFIC_2 in intended for internal use only.") -constexpr wxPGPropertyFlags wxPG_PROP_CLASS_SPECIFIC_2 = wxPG_PROP_RESERVED_2; +constexpr wxPGPropertyFlags wxPG_PROP_CLASS_SPECIFIC_2 = wxPGPropertyFlags::Reserved_2; wxDEPRECATED_BUT_USED_INTERNALLY_MSG("wxPG_PROP_CLASS_SPECIFIC_3 in intended for internal use only.") -constexpr wxPGPropertyFlags wxPG_PROP_CLASS_SPECIFIC_3 = wxPG_PROP_RESERVED_3; +constexpr wxPGPropertyFlags wxPG_PROP_CLASS_SPECIFIC_3 = wxPGPropertyFlags::Reserved_3; #endif // WXWIN_COMPATIBILITY_3_2 -// Topmost flag. -constexpr wxPGPropertyFlags wxPG_PROP_MAX = wxPG_PROP_AUTO_UNSPECIFIED; - -// Property with children must have one of these set, otherwise iterators -// will not work correctly. -// Code should automatically take care of this, however. -#define wxPG_PROP_PARENTAL_FLAGS \ - ((wxPGPropertyFlags)(wxPG_PROP_AGGREGATE | \ - wxPG_PROP_CATEGORY | \ - wxPG_PROP_MISC_PARENT)) - -// Combination of flags that can be stored by GetFlagsAsString -#define wxPG_STRING_STORED_FLAGS \ - (wxPG_PROP_DISABLED|wxPG_PROP_HIDDEN|wxPG_PROP_NOEDITOR|wxPG_PROP_COLLAPSED) - // ----------------------------------------------------------------------- // Helpers to mark macros as deprecated @@ -950,7 +1050,12 @@ class WXDLLIMPEXP_PROPGRID wxPGProperty : public wxObject wxDECLARE_ABSTRACT_CLASS(wxPGProperty); public: +#if WXWIN_COMPATIBILITY_3_0 typedef wxUint32 FlagType; +#elif WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use wxPGPropertyFlags type instead") + typedef wxUint32 FlagType; +#endif // WXWIN_COMPATIBILITY_3_0, WXWIN_COMPATIBILITY_3_2 // Virtual destructor. // It is customary for derived properties to implement this. @@ -1197,7 +1302,7 @@ public: // values of a font). bool AreChildrenComponents() const { - return (m_flags & (wxPG_PROP_COMPOSED_VALUE|wxPG_PROP_AGGREGATE)) != 0; + return !!(m_flags & (wxPGPropertyFlags::ComposedValue|wxPGPropertyFlags::Aggregate)); } // Deletes children of the property. @@ -1219,7 +1324,7 @@ public: // Common values are disabled by the default for all properties. void EnableCommonValue( bool enable = true ) { - ChangeFlag(wxPG_PROP_USES_COMMON_VALUE, enable); + ChangeFlag(wxPGPropertyFlags::UsesCommonValue, enable); } // Composes text from values of child properties. @@ -1348,25 +1453,35 @@ public: #if WXWIN_COMPATIBILITY_3_0 // Returns non-zero if property has given flag set. - FlagType HasFlag( wxPGPropertyFlags flag ) const + wxDEPRECATED_MSG("use HasFlag() with 'flag' argument as wxPGPropertyFlags") + FlagType HasFlag( FlagType flag ) const { - return ( m_flags & flag ); - } -#else - // Returns true if property has given flag set. - bool HasFlag(wxPGPropertyFlags flag) const - { - return (m_flags & flag) != 0; + return ( static_cast(m_flags) & flag ); } #endif // Returns true if property has given flag set. - bool HasFlag(FlagType flag) const + bool HasFlag(wxPGPropertyFlags flag) const { - return (m_flags & flag) != 0; + return !!(m_flags & flag); } +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use HasFlag() with 'flag' argument as wxPGPropertyFlags") + // Returns true if property has given flag set. + bool HasFlag(int flag) const + { + return HasFlag(static_cast(flag)); + } +#endif // WXWIN_COMPATIBILITY_3_2 // Returns true if property has all given flags set. - bool HasFlagsExact(FlagType flags) const +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use HasFlagExact() with 'flags' argument as wxPGPropertyFlags") + bool HasFlagsExact(int flags) const + { + return HasFlagsExact(static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + bool HasFlagsExact(wxPGPropertyFlags flags) const { return (m_flags & flags) == flags; } @@ -1385,7 +1500,7 @@ public: wxDEPRECATED_MSG("Use HasFlag or HasFlagsExact functions instead.") FlagType GetFlags() const { - return m_flags; + return static_cast(m_flags); } #endif @@ -1425,7 +1540,7 @@ public: int InsertChoice( const wxString& label, int index, int value = wxPG_INVALID_VALUE ); // Returns true if this property is actually a wxPropertyCategory. - bool IsCategory() const { return (m_flags & wxPG_PROP_CATEGORY) != 0; } + bool IsCategory() const { return !!(m_flags & wxPGPropertyFlags::Category); } // Returns true if this property is actually a wxRootProperty. bool IsRoot() const { return (m_parent == nullptr); } @@ -1467,7 +1582,7 @@ public: // Returns true if containing grid uses wxPG_EX_AUTO_UNSPECIFIED_VALUES. bool UsesAutoUnspecified() const { - return (m_flags & wxPG_PROP_AUTO_UNSPECIFIED) != 0; + return !!(m_flags & wxPGPropertyFlags::AutoUnspecified); } // Returns bitmap that appears next to value text. Only returns non-null @@ -1492,9 +1607,16 @@ public: unsigned int GetDepth() const { return (unsigned int)m_depth; } // Gets flags as a'|' delimited string. Note that flag names are not - // prepended with 'wxPG_PROP_'. + // prepended with 'wxPGPropertyFlags'. // flagmask - String will only be made to include flags combined by this parameter. - wxString GetFlagsAsString( FlagType flagsMask ) const; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use GetFlagsAsString() with 'flags' argument as wxPGPropertyFlags") + wxString GetFlagsAsString( int flagsMask ) const + { + return GetFlagsAsString(static_cast(flagsMask)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + wxString GetFlagsAsString(wxPGPropertyFlags flagsMask) const; // Returns position in parent's array. unsigned int GetIndexInParent() const @@ -1517,13 +1639,13 @@ public: // Returns true if property has visible children. bool IsExpanded() const - { return (!(m_flags & wxPG_PROP_COLLAPSED) && HasAnyChild()); } + { return (!(m_flags & wxPGPropertyFlags::Collapsed) && HasAnyChild()); } // Returns true if all parents expanded. bool IsVisible() const; // Returns true if property is enabled. - bool IsEnabled() const { return !(m_flags & wxPG_PROP_DISABLED); } + bool IsEnabled() const { return !(m_flags & wxPGPropertyFlags::Disabled); } // If property's editor is created this forces its recreation. // Useful in SetAttribute etc. Returns true if actually did anything. @@ -1549,7 +1671,7 @@ public: // by default). void SetAutoUnspecified( bool enable = true ) { - ChangeFlag(wxPG_PROP_AUTO_UNSPECIFIED, enable); + ChangeFlag(wxPGPropertyFlags::AutoUnspecified, enable); } // Sets property's background colour. @@ -1624,13 +1746,13 @@ public: } // Sets flags from a '|' delimited string. Note that flag names are not - // prepended with 'wxPG_PROP_'. + // prepended with 'wxPGPropertyFlags'. void SetFlagsFromString( const wxString& str ); // Sets property's "is it modified?" flag. Affects children recursively. void SetModifiedStatus( bool modified ) { - SetFlagRecursively(wxPG_PROP_MODIFIED, modified); + SetFlagRecursively(wxPGPropertyFlags::Modified, modified); } // Call in OnEvent(), OnButtonClick() etc. to change the property value @@ -1671,14 +1793,14 @@ public: void SetExpanded( bool expanded ) { - ChangeFlag(wxPG_PROP_COLLAPSED, !expanded); + ChangeFlag(wxPGPropertyFlags::Collapsed, !expanded); } // Sets or clears given property flag. Mainly for internal use. // Setting a property flag never has any side-effect, and is // intended almost exclusively for internal use. So, for // example, if you want to disable a property, call - // Enable(false) instead of setting wxPG_PROP_DISABLED flag. + // Enable(false) instead of setting wxPGPropertyFlags::Disabled flag. void ChangeFlag( wxPGPropertyFlags flag, bool set ) { if ( set ) @@ -1707,14 +1829,21 @@ public: void SetName( const wxString& newName ); // Changes what sort of parent this property is for its children. - // flag - Use one of the following values: wxPG_PROP_MISC_PARENT (for - // generic parents), wxPG_PROP_CATEGORY (for categories), or - // wxPG_PROP_AGGREGATE (for derived property classes with private + // flag - Use one of the following values: wxPGPropertyFlags::MiscParent (for + // generic parents), wxPGPropertyFlags::Category (for categories), or + // wxPGPropertyFlags::Aggregate (for derived property classes with private // children). // You generally do not need to call this function. - void SetParentalType( int flag ) +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use SetParentalType() with 'flag' argument as wxPGPropertyFlags") + void SetParentalType(int flag) { - m_flags &= ~(wxPG_PROP_PROPERTY|wxPG_PROP_PARENTAL_FLAGS); + SetParentalType(static_cast(flag)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + void SetParentalType(wxPGPropertyFlags flag) + { + m_flags &= ~(wxPGPropertyFlags::Property | wxPGPropertyFlags::ParentalFlags); m_flags |= flag; } @@ -1781,7 +1910,7 @@ public: // (i.e. cancel 'true' returned by StringToValue() or IntToValue()). void SetWasModified( bool set = true ) { - ChangeFlag(wxPG_PROP_WAS_MODIFIED, set); + ChangeFlag(wxPGPropertyFlags::WasModified, set); } // Returns property's help or description text. @@ -1801,7 +1930,7 @@ public: // Adds a private child property. If you use this instead of // wxPropertyGridInterface::Insert() or // wxPropertyGridInterface::AppendIn(), then property's parental - // type will automatically be set up to wxPG_PROP_AGGREGATE. In other + // type will automatically be set up to wxPGPropertyFlags::Aggregate. In other // words, all properties of this property will become private. void AddPrivateChild( wxPGProperty* prop ); @@ -1910,17 +2039,38 @@ protected: // preparedCell. // ignoreWithFlags - Properties with any one of these flags are skipped. // recursively - If true, apply this operation recursively in child properties. +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use AdaptiveSetCell() with 'ignoreWithFlags' argument as wxPGPropertyFlags") void AdaptiveSetCell( unsigned int firstCol, unsigned int lastCol, const wxPGCell& preparedCell, const wxPGCell& srcData, wxPGCellData* unmodCellData, - FlagType ignoreWithFlags, - bool recursively ); + int ignoreWithFlags, + bool recursively ) + { + AdaptiveSetCell(firstCol, lastCol, preparedCell, srcData, unmodCellData, + static_cast(ignoreWithFlags), recursively); + } +#endif // WXWIN_COMPATIBILITY_3_2 + void AdaptiveSetCell(unsigned int firstCol, + unsigned int lastCol, + const wxPGCell& preparedCell, + const wxPGCell& srcData, + wxPGCellData* unmodCellData, + wxPGPropertyFlags ignoreWithFlags, + bool recursively); // Clear cells associated with property. // recursively - If true, apply this operation recursively in child properties. - void ClearCells(FlagType ignoreWithFlags, bool recursively); +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ClearCells() with 'ignoreWithFlags' argument as wxPGPropertyFlags") + void ClearCells(int ignoreWithFlags, bool recursively) + { + ClearCells(static_cast(ignoreWithFlags), recursively); + } +#endif // WXWIN_COMPATIBILITY_3_2 + void ClearCells(wxPGPropertyFlags ignoreWithFlags, bool recursively); // Makes sure m_cells has size of column+1 (or more). void EnsureCells( unsigned int column ); @@ -1989,7 +2139,17 @@ protected: m_flags |= flag; } - void ClearFlag( FlagType flag ) { m_flags &= ~(flag); } +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ClearFlag() with 'flag' argument as wxPGPropertyFlags") + void ClearFlag( int flag ) + { + ClearFlag(static_cast(flag)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + void ClearFlag(wxPGPropertyFlags flag) + { + m_flags &= ~(flag); + } // Called when the property is being removed from the grid and/or // page state (but *not* when it is also deleted). @@ -2041,7 +2201,7 @@ protected: // If not -1, then overrides m_value int m_commonValue; - FlagType m_flags; + wxPGPropertyFlags m_flags; // Maximum length (for string properties). Could be in some sort of // wxBaseStringProperty, but currently, for maximum flexibility and diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index 8e8a5ba597..0dd0a0da89 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -250,7 +250,7 @@ wxPG_EX_HELP_AS_TOOLTIPS = 0x00010000, wxPG_EX_NATIVE_DOUBLE_BUFFERING = 0x00080000, // Set this style to let user have ability to set values of properties to -// unspecified state. Same as setting wxPG_PROP_AUTO_UNSPECIFIED for +// unspecified state. Same as setting wxPGPropertyFlags::AutoUnspecified for // all properties. wxPG_EX_AUTO_UNSPECIFIED_VALUES = 0x00200000, @@ -1300,10 +1300,10 @@ public: // Called to indicate property and editor has valid value now. void OnValidationFailureReset( wxPGProperty* property ) { - if ( property && property->HasFlag(wxPG_PROP_INVALID_VALUE) ) + if ( property && property->HasFlag(wxPGPropertyFlags::InvalidValue) ) { DoOnValidationFailureReset(property); - property->ClearFlag(wxPG_PROP_INVALID_VALUE); + property->ClearFlag(wxPGPropertyFlags::InvalidValue); } m_validationInfo.ClearFailureMessage(); } @@ -1337,7 +1337,7 @@ public: wxVariant& invalidValue ); // Override to customize resetting of property validation failure status. - // Property is guaranteed to have flag wxPG_PROP_INVALID_VALUE set. + // Property is guaranteed to have flag wxPGPropertyFlags::InvalidValue set. virtual void DoOnValidationFailureReset( wxPGProperty* property ); int GetSpacingY() const { return m_spacingy; } diff --git a/include/wx/propgrid/propgridiface.h b/include/wx/propgrid/propgridiface.h index ac229bcf2f..40a6c48fc3 100644 --- a/include/wx/propgrid/propgridiface.h +++ b/include/wx/propgrid/propgridiface.h @@ -331,7 +331,7 @@ public: { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty) - if ( !p->HasAnyChild() || p->HasFlag(wxPG_PROP_AGGREGATE) ) + if ( !p->HasAnyChild() || p->HasFlag(wxPGPropertyFlags::Aggregate) ) return wxNullProperty; return p->Item(0); @@ -410,12 +410,24 @@ public: // only properties without given flags are stored. // flags - Property flags to use. // iterFlags - Iterator flags to use. Default is everything expect private children. +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use GetPropertiesWithFlag() with 'flags' argument as wxPGPropertyFlags") void GetPropertiesWithFlag( wxArrayPGProperty* targetArr, - wxPGProperty::FlagType flags, + int flags, bool inverse = false, int iterFlags = wxPG_ITERATE_PROPERTIES | wxPG_ITERATE_HIDDEN | - wxPG_ITERATE_CATEGORIES) const; + wxPG_ITERATE_CATEGORIES) const + { + GetPropertiesWithFlag(targetArr, static_cast(flags), inverse, iterFlags); + } +#endif // WXWIN_COMPATIBILITY_3_2 + void GetPropertiesWithFlag(wxArrayPGProperty* targetArr, + wxPGPropertyFlags flags, + bool inverse = false, + int iterFlags = wxPG_ITERATE_PROPERTIES | + wxPG_ITERATE_HIDDEN | + wxPG_ITERATE_CATEGORIES) const; // Returns value of given attribute. If none found, returns null wxVariant. wxVariant GetPropertyAttribute( wxPGPropArg id, @@ -652,7 +664,7 @@ public: bool IsPropertyEnabled( wxPGPropArg id ) const { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false) - return !p->HasFlag(wxPG_PROP_DISABLED); + return !p->HasFlag(wxPGPropertyFlags::Disabled); } // Returns true if given property is expanded. @@ -664,11 +676,7 @@ public: bool IsPropertyModified( wxPGPropArg id ) const { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false) -#if WXWIN_COMPATIBILITY_3_0 - return p->HasFlag(wxPG_PROP_MODIFIED)?true:false; -#else - return p->HasFlag(wxPG_PROP_MODIFIED); -#endif + return p->HasFlag(wxPGPropertyFlags::Modified); } // Returns true if property is selected. @@ -683,7 +691,7 @@ public: bool IsPropertyShown( wxPGPropArg id ) const { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false) - return !p->HasFlag(wxPG_PROP_HIDDEN); + return !p->HasFlag(wxPGPropertyFlags::Hidden); } // Returns true if property value is set to unspecified. diff --git a/include/wx/propgrid/propgridpagestate.h b/include/wx/propgrid/propgridpagestate.h index 60904042dd..e6c87c625c 100644 --- a/include/wx/propgrid/propgridpagestate.h +++ b/include/wx/propgrid/propgridpagestate.h @@ -213,54 +213,54 @@ enum wxPG_ITERATOR_FLAGS // Iterate through 'normal' property items (does not include children of // aggregate or hidden items by default). -wxPG_ITERATE_PROPERTIES = wxPG_PROP_PROPERTY | - wxPG_PROP_MISC_PARENT | - wxPG_PROP_AGGREGATE | - wxPG_PROP_COLLAPSED | - wxPG_IT_CHILDREN(wxPG_PROP_MISC_PARENT) | - wxPG_IT_CHILDREN(wxPG_PROP_CATEGORY), +wxPG_ITERATE_PROPERTIES = wxPGPropertyFlags::Property | + wxPGPropertyFlags::MiscParent | + wxPGPropertyFlags::Aggregate | + wxPGPropertyFlags::Collapsed | + wxPG_IT_CHILDREN(wxPGPropertyFlags::MiscParent) | + wxPG_IT_CHILDREN(wxPGPropertyFlags::Category), // Iterate children of collapsed parents, and individual items that are hidden. -wxPG_ITERATE_HIDDEN = wxPG_PROP_HIDDEN | - wxPG_IT_CHILDREN(wxPG_PROP_COLLAPSED), +wxPG_ITERATE_HIDDEN = wxPGPropertyFlags::Hidden | + wxPG_IT_CHILDREN(wxPGPropertyFlags::Collapsed), // Iterate children of parent that is an aggregate property (ie has fixed // children). -wxPG_ITERATE_FIXED_CHILDREN = wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE) | +wxPG_ITERATE_FIXED_CHILDREN = wxPG_IT_CHILDREN(wxPGPropertyFlags::Aggregate) | wxPG_ITERATE_PROPERTIES, // Iterate categories. // Note that even without this flag, children of categories are still iterated // through. -wxPG_ITERATE_CATEGORIES = wxPG_PROP_CATEGORY | - wxPG_IT_CHILDREN(wxPG_PROP_CATEGORY) | - wxPG_PROP_COLLAPSED, +wxPG_ITERATE_CATEGORIES = wxPGPropertyFlags::Category | + wxPG_IT_CHILDREN(wxPGPropertyFlags::Category) | + wxPGPropertyFlags::Collapsed, -wxPG_ITERATE_ALL_PARENTS = wxPG_PROP_MISC_PARENT | - wxPG_PROP_AGGREGATE | - wxPG_PROP_CATEGORY, +wxPG_ITERATE_ALL_PARENTS = static_cast(wxPGPropertyFlags::MiscParent | + wxPGPropertyFlags::Aggregate | + wxPGPropertyFlags::Category), wxPG_ITERATE_ALL_PARENTS_RECURSIVELY = wxPG_ITERATE_ALL_PARENTS | wxPG_IT_CHILDREN( wxPG_ITERATE_ALL_PARENTS), -wxPG_ITERATOR_FLAGS_ALL = wxPG_PROP_PROPERTY | - wxPG_PROP_MISC_PARENT | - wxPG_PROP_AGGREGATE | - wxPG_PROP_HIDDEN | - wxPG_PROP_CATEGORY | - wxPG_PROP_COLLAPSED, +wxPG_ITERATOR_FLAGS_ALL = static_cast(wxPGPropertyFlags::Property | + wxPGPropertyFlags::MiscParent | + wxPGPropertyFlags::Aggregate | + wxPGPropertyFlags::Hidden | + wxPGPropertyFlags::Category | + wxPGPropertyFlags::Collapsed), wxPG_ITERATOR_MASK_OP_ITEM = wxPG_ITERATOR_FLAGS_ALL, -// (wxPG_PROP_MISC_PARENT|wxPG_PROP_AGGREGATE|wxPG_PROP_CATEGORY) +// (wxPGPropertyFlags::MiscParent|wxPGPropertyFlags::Aggregate|wxPGPropertyFlags::Category) wxPG_ITERATOR_MASK_OP_PARENT = wxPG_ITERATOR_FLAGS_ALL, // Combines all flags needed to iterate through visible properties // (ie. hidden properties and children of collapsed parents are skipped). -wxPG_ITERATE_VISIBLE = static_cast(wxPG_ITERATE_PROPERTIES) | - wxPG_PROP_CATEGORY | - wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE), +wxPG_ITERATE_VISIBLE = wxPG_ITERATE_PROPERTIES | + wxPGPropertyFlags::Category | + wxPG_IT_CHILDREN(wxPGPropertyFlags::Aggregate), // Iterate all items. wxPG_ITERATE_ALL = wxPG_ITERATE_VISIBLE | @@ -278,10 +278,10 @@ wxPG_ITERATE_DEFAULT = wxPG_ITERATE_NORMAL #define wxPG_ITERATOR_CREATE_MASKS(FLAGS, A, B) \ - A = (FLAGS ^ wxPG_ITERATOR_MASK_OP_ITEM) & \ - wxPG_ITERATOR_MASK_OP_ITEM & 0xFFFF; \ - B = ((FLAGS>>16) ^ wxPG_ITERATOR_MASK_OP_PARENT) & \ - wxPG_ITERATOR_MASK_OP_PARENT & 0xFFFF; + A = static_cast((FLAGS ^ wxPG_ITERATOR_MASK_OP_ITEM) & \ + wxPG_ITERATOR_MASK_OP_ITEM & 0xFFFF); \ + B = static_cast(((FLAGS>>16) ^ wxPG_ITERATOR_MASK_OP_PARENT) & \ + wxPG_ITERATOR_MASK_OP_PARENT & 0xFFFF); // Macro to test if children of PWC should be iterated through @@ -337,8 +337,8 @@ private: wxPGProperty* m_baseParent; // Masks are used to quickly exclude items - wxPGProperty::FlagType m_itemExMask; - wxPGProperty::FlagType m_parentExMask; + wxPGPropertyFlags m_itemExMask; + wxPGPropertyFlags m_parentExMask; }; template @@ -640,7 +640,7 @@ protected: void DoLimitPropertyEditing(wxPGProperty* p, bool limit = true) { - p->SetFlagRecursively(wxPG_PROP_NOEDITOR, limit); + p->SetFlagRecursively(wxPGPropertyFlags::NoEditor, limit); } bool DoSelectProperty(wxPGProperty* p, wxPGSelectPropertyFlags flags = wxPGSelectPropertyFlags::Null); diff --git a/include/wx/propgrid/props.h b/include/wx/propgrid/props.h index 91e6e064ab..cdae89c8e0 100644 --- a/include/wx/propgrid/props.h +++ b/include/wx/propgrid/props.h @@ -335,8 +335,8 @@ public: #if WXWIN_COMPATIBILITY_3_2 // If set, then selection of choices is static and should not be // changed (i.e. returns nullptr in GetPropertyChoices). -wxDEPRECATED_BUT_USED_INTERNALLY_MSG("wxPG_PROP_STATIC_CHOICES is intended for internal use.") -constexpr wxPGPropertyFlags wxPG_PROP_STATIC_CHOICES = wxPG_PROP_RESERVED_1; +wxDEPRECATED_MSG("wxPG_PROP_STATIC_CHOICES is intended for internal use.") +constexpr wxPGPropertyFlags wxPG_PROP_STATIC_CHOICES = wxPGPropertyFlags::Reserved_1; #endif // WXWIN_COMPATIBILITY_3_2 // Represents a single selection from a list of choices @@ -581,8 +581,8 @@ protected: #if WXWIN_COMPATIBILITY_3_2 // Indicates first bit usable by derived properties. -wxDEPRECATED_BUT_USED_INTERNALLY_MSG("wxPG_PROP_SHOW_FULL_FILENAME is intended for internal use.") -constexpr wxPGPropertyFlags wxPG_PROP_SHOW_FULL_FILENAME = wxPG_PROP_RESERVED_1; +wxDEPRECATED_MSG("wxPG_PROP_SHOW_FULL_FILENAME is intended for internal use.") +constexpr wxPGPropertyFlags wxPG_PROP_SHOW_FULL_FILENAME = wxPGPropertyFlags::Reserved_1; #endif // WXWIN_COMPATIBILITY_3_2 // Like wxLongStringProperty, but the button triggers file selector instead. @@ -623,8 +623,8 @@ protected: #if WXWIN_COMPATIBILITY_3_2 // Flag used in wxLongStringProperty to mark that edit button // should be enabled even in the read-only mode. -wxDEPRECATED_BUT_USED_INTERNALLY_MSG("wxPG_PROP_ACTIVE_BTN is intended for internal use.") -constexpr wxPGPropertyFlags wxPG_PROP_ACTIVE_BTN = wxPG_PROP_RESERVED_3; +wxDEPRECATED_MSG("wxPG_PROP_ACTIVE_BTN is intended for internal use.") +constexpr wxPGPropertyFlags wxPG_PROP_ACTIVE_BTN = wxPGPropertyFlags::Reserved_3; #endif // WXWIN_COMPATIBILITY_3_2 // Like wxStringProperty, but has a button that triggers a small text diff --git a/interface/wx/propgrid/property.h b/interface/wx/propgrid/property.h index debf028d9a..191a2fc729 100644 --- a/interface/wx/propgrid/property.h +++ b/interface/wx/propgrid/property.h @@ -235,157 +235,163 @@ struct wxPGPaintData @{ */ -enum wxPGPropertyFlags +enum class wxPGPropertyFlags : int { + /** No flags. + @hideinitializer + */ + Null = 0, -/** Indicates bold font. - @hideinitializer -*/ -wxPG_PROP_MODIFIED = 0x0001, + /** Indicates bold font. + @hideinitializer + */ + Modified = 0x0001, -/** Disables ('greyed' text and editor does not activate) property. - @hideinitializer -*/ -wxPG_PROP_DISABLED = 0x0002, + /** Disables ('greyed' text and editor does not activate) property. + @hideinitializer + */ + Disabled = 0x0002, -/** Hider button will hide this property. - @hideinitializer -*/ -wxPG_PROP_HIDDEN = 0x0004, + /** Hider button will hide this property. + @hideinitializer + */ + Hidden = 0x0004, -/** This property has custom paint image just in front of its value. - If property only draws custom images into a popup list, then this - flag should not be set. - @hideinitializer -*/ -wxPG_PROP_CUSTOMIMAGE = 0x0008, + /** This property has custom paint image just in front of its value. + If property only draws custom images into a popup list, then this + flag should not be set. + @hideinitializer + */ + CustomImage = 0x0008, -/** Do not create text based editor for this property (but button-triggered - dialog and choice are ok). - @hideinitializer -*/ -wxPG_PROP_NOEDITOR = 0x0010, + /** Do not create text based editor for this property (but button-triggered + dialog and choice are ok). + @hideinitializer + */ + NoEditor = 0x0010, -/** Property is collapsed, ie. it's children are hidden. - @hideinitializer -*/ -wxPG_PROP_COLLAPSED = 0x0020, + /** Property is collapsed, ie. it's children are hidden. + @hideinitializer + */ + Collapsed = 0x0020, -/** - If property is selected, then indicates that validation failed for pending - value. + /** If property is selected, then indicates that validation failed for pending + value. - If property is not selected, then indicates that the actual property - value has failed validation (NB: this behaviour is not currently supported, - but may be used in the future). - @hideinitializer -*/ -wxPG_PROP_INVALID_VALUE = 0x0040, + If property is not selected, then indicates that the actual property + value has failed validation (NB: this behaviour is not currently supported, + but may be used in the future). + @hideinitializer + */ + InvalidValue = 0x0040, -/** Switched via SetWasModified(). Temporary flag - only used when - setting/changing property value. - @hideinitializer -*/ -wxPG_PROP_WAS_MODIFIED = 0x0200, + /** Switched via SetWasModified(). Temporary flag - only used when + setting/changing property value. + @hideinitializer + */ + WasModified = 0x0200, -/** - If set, then child properties (if any) are private, and should be - "invisible" to the application. - @hideinitializer -*/ -wxPG_PROP_AGGREGATE = 0x0400, + /** If set, then child properties (if any) are private, and should be + "invisible" to the application. + @hideinitializer + */ + Aggregate = 0x0400, -/** If set, then child properties (if any) are copies and should not - be deleted in dtor. - @hideinitializer -*/ -wxPG_PROP_CHILDREN_ARE_COPIES = 0x0800, + /** If set, then child properties (if any) are copies and should not + be deleted in dtor. + @hideinitializer + */ + ChildrenAreCopies = 0x0800, -/** - Classifies this item as a non-category. + /** Classifies this item as a non-category. + Used for faster item type identification. + @hideinitializer + */ + Property = 0x1000, - Used for faster item type identification. - @hideinitializer -*/ -wxPG_PROP_PROPERTY = 0x1000, -/** - Classifies this item as a category. + /** Classifies this item as a category. + Used for faster item type identification. + @hideinitializer + */ + Category = 0x2000, - Used for faster item type identification. - @hideinitializer -*/ -wxPG_PROP_CATEGORY = 0x2000, + /** Classifies this item as a property that has children, but is not aggregate + (i.e. children are not private). + @hideinitializer + */ + MiscParent = 0x4000, -/** Classifies this item as a property that has children, but is not aggregate - (i.e. children are not private). - @hideinitializer -*/ -wxPG_PROP_MISC_PARENT = 0x4000, -/** Property is read-only. Editor is still created for wxTextCtrl-based - property editors. For others, editor is not usually created because - they do implement wxTE_READONLY style or equivalent. - @hideinitializer -*/ -wxPG_PROP_READONLY = 0x8000, + /** Property is read-only. Editor is still created for wxTextCtrl-based + property editors. For others, editor is not usually created because + they do implement wxTE_READONLY style or equivalent. + @hideinitializer + */ + ReadOnly = 0x8000, -// -// NB: FLAGS ABOVE 0x8000 CANNOT BE USED WITH PROPERTY ITERATORS -// + // + // NB: FLAGS ABOVE 0x8000 CANNOT BE USED WITH PROPERTY ITERATORS + // -/** Property's value is composed from values of child properties. - @remarks - This flag cannot be used with property iterators. - @hideinitializer -*/ -wxPG_PROP_COMPOSED_VALUE = 0x00010000, + /** Property's value is composed from values of child properties. + @remarks + This flag cannot be used with property iterators. + @hideinitializer + */ + ComposedValue = 0x00010000, -/** Common value of property is selectable in editor. - @remarks - This flag cannot be used with property iterators. - @hideinitializer -*/ -wxPG_PROP_USES_COMMON_VALUE = 0x00020000, + /** Common value of property is selectable in editor. + @remarks + This flag cannot be used with property iterators. + @hideinitializer + */ + UsesCommonValue = 0x00020000, -/** Property can be set to unspecified value via editor. - Currently, this applies to following properties: - - wxIntProperty, wxUIntProperty, wxFloatProperty, wxEditEnumProperty: - Clear the text field + /** Property can be set to unspecified value via editor. + Currently, this applies to following properties: + - wxIntProperty, wxUIntProperty, wxFloatProperty, wxEditEnumProperty: + Clear the text field - @remarks - This flag cannot be used with property iterators. + @remarks + This flag cannot be used with property iterators. - @see wxPGProperty::SetAutoUnspecified() - @hideinitializer -*/ -wxPG_PROP_AUTO_UNSPECIFIED = 0x00040000, + @see wxPGProperty::SetAutoUnspecified() + @hideinitializer + */ -/** Indicates that the property is being deleted and should be ignored. - @hideinitializer -*/ -wxPG_PROP_BEING_DELETED = 0x00200000 + /** Indicates that the property is being deleted and should be ignored. + @remarks + This flag cannot be used with property iterators. + @hideinitializer + */ + BeingDeleted = 0x00080000, + + /** If set, full path is shown in wxFileProperty. + @remarks + This flag cannot be used with property iterators. + @hideinitializer + */ + ShowFullFileName = 0x00100000, + + /** Topmost flag. + @hideinitializer + */ + Max = ShowFullFileName, + + /** Property with children must have one of these set, otherwise iterators + will not work correctly. + Code should automatically take care of this, however. + @hideinitializer + */ + ParentalFlags = Aggregate | Category | MiscParent, + + /** Combination of flags that can be stored by GetFlagsAsString(). + @hideinitializer + */ + StringStoredFlags = Disabled | Hidden | NoEditor | Collapsed }; -/** Topmost flag. - @hideinitializer -*/ -constexpr wxPGPropertyFlags wxPG_PROP_MAX = wxPG_PROP_AUTO_UNSPECIFIED; - -/** Property with children must have one of these set, otherwise iterators - will not work correctly. - Code should automatically take care of this, however. -*/ -#define wxPG_PROP_PARENTAL_FLAGS \ - ((wxPGPropertyFlags)(wxPG_PROP_AGGREGATE | \ - wxPG_PROP_CATEGORY | \ - wxPG_PROP_MISC_PARENT)) - -/** Combination of flags that can be stored by GetFlagsAsString(). -*/ -#define wxPG_STRING_STORED_FLAGS \ - (wxPG_PROP_DISABLED|wxPG_PROP_HIDDEN|wxPG_PROP_NOEDITOR|wxPG_PROP_COLLAPSED) - /** @} */ @@ -591,13 +597,6 @@ constexpr wxPGPropertyFlags wxPG_PROP_MAX = wxPG_PROP_AUTO_UNSPECIFIED; } @endcode - Also, if you wish not to have line breaks and tabs translated to - escape sequences, then do following in constructor of your subclass: - - @code - m_flags |= wxPG_PROP_NO_ESCAPE; - @endcode - Supported special attributes: - ::wxPG_DIALOG_TITLE: Sets a specific title for the text editor dialog. @@ -867,8 +866,6 @@ constexpr wxPGPropertyFlags wxPG_PROP_MAX = wxPG_PROP_AUTO_UNSPECIFIED; class wxPGProperty : public wxObject { public: - typedef wxUint32 FlagType; - /** Virtual destructor. It is customary for derived properties to implement this. */ @@ -1285,8 +1282,8 @@ public: Adds a private child property. If you use this instead of wxPropertyGridInterface::Insert() or wxPropertyGridInterface::AppendIn(), then property's parental - type will automatically be set up to ::wxPG_PROP_AGGREGATE. In other - words, all properties of this property will become private. + type will automatically be set up to wxPGPropertyFlags::Aggregate. + In other words, all properties of this property will become private. */ void AddPrivateChild( wxPGProperty* prop ); @@ -1331,7 +1328,7 @@ public: intended almost exclusively for internal use. So, for example, if you want to disable a property, call @code Enable(false) @endcode instead of setting - ::wxPG_PROP_DISABLED flag. + wxPGPropertyFlags::Disabled flag. @see HasFlag(), GetFlags() */ @@ -1549,12 +1546,12 @@ public: const wxString& GetHelpString() const; /** Gets flags as a'|' delimited string. Note that flag names are not - prepended with 'wxPG_PROP_'. + prepended with 'wxPGPropertyFlags'. @param flagsMask String will only be made to include flags combined by this parameter. */ - wxString GetFlagsAsString( FlagType flagsMask ) const; + wxString GetFlagsAsString(wxPGPropertyFlags flagsMask) const; /** Returns position in parent's array. @@ -1667,15 +1664,10 @@ public: */ bool HasFlag(wxPGPropertyFlags flag) const; - /** - Returns @true if property has given flag set. - */ - bool HasFlag(FlagType flag) const; - /** Returns @true if property has all given flags set. */ - bool HasFlagsExact(FlagType flags) const; + bool HasFlagsExact(wxPGPropertyFlags flags) const; /** Returns @true if property has even one visible child. @@ -1912,7 +1904,7 @@ public: void SetExpanded( bool expanded ); /** Sets flags from a '|' delimited string. Note that flag names are not - prepended with 'wxPG_PROP_'. + prepended with 'wxPGPropertyFlags'. */ void SetFlagsFromString( const wxString& str ); @@ -1971,14 +1963,14 @@ public: Changes what sort of parent this property is for its children. @param flag - Use one of the following values: ::wxPG_PROP_MISC_PARENT (for generic - parents), ::wxPG_PROP_CATEGORY (for categories), or - ::wxPG_PROP_AGGREGATE (for derived property classes with private - children). + Use one of the following values: wxPGPropertyFlags::MiscParent (for + generic parents), wxPGPropertyFlags::Category (for categories), or + wxPGPropertyFlags::Aggregate (for derived property classes with + private children). @remarks You generally do not need to call this function. */ - void SetParentalType( int flag ); + void SetParentalType(wxPGPropertyFlags flag); /** Sets property's text colour. @@ -2157,7 +2149,7 @@ protected: const wxPGCell& preparedCell, const wxPGCell& srcData, wxPGCellData* unmodCellData, - FlagType ignoreWithFlags, + wxPGPropertyFlags ignoreWithFlags, bool recursively ); /** @@ -2171,7 +2163,7 @@ protected: @since 3.1.0 */ - void ClearCells(FlagType ignoreWithFlags, bool recursively); + void ClearCells(wxPGPropertyFlags ignoreWithFlags, bool recursively); /** Makes sure m_cells has size of column+1 (or more). diff --git a/interface/wx/propgrid/propgrid.h b/interface/wx/propgrid/propgrid.h index 886704a705..29c1e25cbb 100644 --- a/interface/wx/propgrid/propgrid.h +++ b/interface/wx/propgrid/propgrid.h @@ -166,8 +166,8 @@ wxPG_EX_NATIVE_DOUBLE_BUFFERING = 0x00080000, /** Set this style to let user have ability to set values of properties to - unspecified state. Same as setting wxPG_PROP_AUTO_UNSPECIFIED for - all properties. + unspecified state. Same as setting wxPGPropertyFlags::AutoUnspecified + for all properties. @hideinitializer */ wxPG_EX_AUTO_UNSPECIFIED_VALUES = 0x00200000, @@ -897,7 +897,8 @@ public: Note that @a column must not be equal to 1, as the second column is always editable and can be made read-only only on cell-by-cell basis - using @code wxPGProperty::ChangeFlag(wxPG_PROP_READONLY, true) @endcode + using + @code wxPGProperty::ChangeFlag(wxPGPropertyFlags::ReadOnly, true) @endcode @see BeginLabelEdit(), EndLabelEdit() */ @@ -1200,7 +1201,7 @@ public: /** Override to customize resetting of property validation failure status. @remarks - Property is guaranteed to have flag ::wxPG_PROP_INVALID_VALUE set. + Property is guaranteed to have flag wxPGPropertyFlags::InvalidValue set. */ virtual void DoOnValidationFailureReset( wxPGProperty* property ); diff --git a/interface/wx/propgrid/propgridiface.h b/interface/wx/propgrid/propgridiface.h index 35b65c1362..acbb9a4263 100644 --- a/interface/wx/propgrid/propgridiface.h +++ b/interface/wx/propgrid/propgridiface.h @@ -368,7 +368,7 @@ public: See @ref propgrid_iterator_flags. */ void GetPropertiesWithFlag( wxArrayPGProperty* targetArr, - wxPGProperty::FlagType flags, + wxPGPropertyFlags flags, bool inverse = false, int iterFlags = (wxPG_ITERATE_PROPERTIES|wxPG_ITERATE_HIDDEN|wxPG_ITERATE_CATEGORIES) ) const; diff --git a/interface/wx/propgrid/propgridpagestate.h b/interface/wx/propgrid/propgridpagestate.h index 08180fe7c9..8040ab6b36 100644 --- a/interface/wx/propgrid/propgridpagestate.h +++ b/interface/wx/propgrid/propgridpagestate.h @@ -120,26 +120,26 @@ enum wxPG_ITERATOR_FLAGS aggregate or hidden items by default). @hideinitializer */ -wxPG_ITERATE_PROPERTIES = wxPG_PROP_PROPERTY | - wxPG_PROP_MISC_PARENT | - wxPG_PROP_AGGREGATE | - wxPG_PROP_COLLAPSED | - wxPG_IT_CHILDREN(wxPG_PROP_MISC_PARENT) | - wxPG_IT_CHILDREN(wxPG_PROP_CATEGORY), +wxPG_ITERATE_PROPERTIES = wxPGPropertyFlags::Property | + wxPGPropertyFlags::MiscParent | + wxPGPropertyFlags::Aggregate | + wxPGPropertyFlags::Collapsed | + wxPG_IT_CHILDREN(wxPGPropertyFlags::MiscParent) | + wxPG_IT_CHILDREN(wxPGPropertyFlags::Category), /** Iterate children of collapsed parents, and individual items that are hidden. @hideinitializer */ -wxPG_ITERATE_HIDDEN = wxPG_PROP_HIDDEN | - wxPG_IT_CHILDREN(wxPG_PROP_COLLAPSED), +wxPG_ITERATE_HIDDEN = wxPGPropertyFlags::Hidden | + wxPG_IT_CHILDREN(wxPGPropertyFlags::Collapsed), /** Iterate children of parent that is an aggregate property (ie has fixed children). @hideinitializer */ -wxPG_ITERATE_FIXED_CHILDREN = wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE) | +wxPG_ITERATE_FIXED_CHILDREN = wxPG_IT_CHILDREN(wxPGPropertyFlags::Aggregate) | wxPG_ITERATE_PROPERTIES, /** Iterate categories. @@ -147,16 +147,16 @@ wxPG_ITERATE_FIXED_CHILDREN = wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE) | through. @hideinitializer */ -wxPG_ITERATE_CATEGORIES = wxPG_PROP_CATEGORY | - wxPG_IT_CHILDREN(wxPG_PROP_CATEGORY) | - wxPG_PROP_COLLAPSED, +wxPG_ITERATE_CATEGORIES = wxPGPropertyFlags::Category | + wxPG_IT_CHILDREN(wxPGPropertyFlags::Category) | + wxPGPropertyFlags::Collapsed, /** @hideinitializer */ -wxPG_ITERATE_ALL_PARENTS = wxPG_PROP_MISC_PARENT | - wxPG_PROP_AGGREGATE | - wxPG_PROP_CATEGORY, +wxPG_ITERATE_ALL_PARENTS = wxPGPropertyFlags::MiscParent | + wxPGPropertyFlags::Aggregate | + wxPGPropertyFlags::Category, /** @hideinitializer @@ -168,19 +168,18 @@ wxPG_ITERATE_ALL_PARENTS_RECURSIVELY = wxPG_ITERATE_ALL_PARENTS | /** @hideinitializer */ -wxPG_ITERATOR_FLAGS_ALL = wxPG_PROP_PROPERTY | - wxPG_PROP_MISC_PARENT | - wxPG_PROP_AGGREGATE | - wxPG_PROP_HIDDEN | - wxPG_PROP_CATEGORY | - wxPG_PROP_COLLAPSED, +wxPG_ITERATOR_FLAGS_ALL = wxPGPropertyFlags::Property | + wxPGPropertyFlags::MiscParent | + wxPGPropertyFlags::Aggregate | + wxPGPropertyFlags::Hidden | + wxPGPropertyFlags::Category | + wxPGPropertyFlags::Collapsed, /** @hideinitializer */ wxPG_ITERATOR_MASK_OP_ITEM = wxPG_ITERATOR_FLAGS_ALL, -// (wxPG_PROP_MISC_PARENT|wxPG_PROP_AGGREGATE|wxPG_PROP_CATEGORY) /** @hideinitializer */ @@ -192,8 +191,8 @@ wxPG_ITERATOR_MASK_OP_PARENT = wxPG_ITERATOR_FLAGS_ALL, @hideinitializer */ wxPG_ITERATE_VISIBLE = wxPG_ITERATE_PROPERTIES | - wxPG_PROP_CATEGORY | - wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE), + wxPGPropertyFlags::Category | + wxPG_IT_CHILDREN(wxPGPropertyFlags::Aggregate), /** Iterate all items. diff --git a/src/propgrid/advprops.cpp b/src/propgrid/advprops.cpp index f7f4ef3f5d..2085242197 100644 --- a/src/propgrid/advprops.cpp +++ b/src/propgrid/advprops.cpp @@ -758,14 +758,6 @@ void wxFontProperty::OnCustomPaint(wxDC& dc, // wxSystemColourProperty // ----------------------------------------------------------------------- -#if WXWIN_COMPATIBILITY_3_2 -// wxEnumProperty based classes cannot use wxPG_PROP_RESERVED_1 -wxDEPRECATED_BUT_USED_INTERNALLY_MSG("wxPG_PROP_HIDE_CUSTOM_COLOUR is intended for internal use.") -constexpr wxPGPropertyFlags wxPG_PROP_HIDE_CUSTOM_COLOUR = wxPG_PROP_RESERVED_2; -wxDEPRECATED_BUT_USED_INTERNALLY_MSG("wxPG_PROP_COLOUR_HAS_ALPHA is intended for internal use.") -constexpr wxPGPropertyFlags wxPG_PROP_COLOUR_HAS_ALPHA = wxPG_PROP_RESERVED_3; -#endif // if WXWIN_COMPATIBILITY_3_2 - #include "wx/colordlg.h" static const char* const gs_cp_es_syscolour_labels[] = { @@ -846,7 +838,7 @@ void wxSystemColourProperty::Init( int type, const wxColour& colour ) cpv.Init(type, colour.IsOk() ? colour : *wxWHITE); - m_flags |= wxPG_PROP_STATIC_CHOICES; // Colour selection cannot be changed. + m_flags |= wxPGPropertyFlags_StaticChoices; // Colour selection cannot be changed. m_value = WXVARIANT(cpv); @@ -1024,7 +1016,7 @@ void wxSystemColourProperty::OnSetValue() } if ( cpv.m_type < wxPG_COLOUR_WEB_BASE || - (m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) ) + !!(m_flags & wxPGPropertyFlags_HideCustomColour) ) { ind = GetIndexForValue(cpv.m_type); } @@ -1049,7 +1041,7 @@ void wxSystemColourProperty::OnSetValue() ind = ColToInd(col); if ( ind == wxNOT_FOUND && - !(m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) ) + !(m_flags & wxPGPropertyFlags_HideCustomColour) ) ind = GetCustomColourIndex(); } @@ -1070,7 +1062,7 @@ wxString wxSystemColourProperty::ColourToString( const wxColour& col, if ( index == wxNOT_FOUND ) { - if ( (argFlags & wxPG_FULL_VALUE) || (m_flags & wxPG_PROP_COLOUR_HAS_ALPHA) ) + if ( (argFlags & wxPG_FULL_VALUE) || !!(m_flags & wxPGPropertyFlags_ColourHasAlpha) ) { return wxString::Format(wxS("(%i,%i,%i,%i)"), (int)col.Red(), @@ -1108,7 +1100,7 @@ wxString wxSystemColourProperty::ValueToString( wxVariant& value, // If custom colour was selected, use invalid index, so that // ColourToString() will return properly formatted colour text. if ( index == GetCustomColourIndex() && - !(m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) ) + !(m_flags & wxPGPropertyFlags_HideCustomColour) ) index = wxNOT_FOUND; } else @@ -1150,7 +1142,7 @@ bool wxSystemColourProperty::QueryColourFromUser( wxVariant& variant ) const wxColourData data; data.SetChooseFull(true); - data.SetChooseAlpha((m_flags & wxPG_PROP_COLOUR_HAS_ALPHA) != 0); + data.SetChooseAlpha(!!(m_flags & wxPGPropertyFlags_ColourHasAlpha)); data.SetColour(val.m_colour); for ( int i = 0; i < wxColourData::NUM_CUSTOM; i++ ) { @@ -1223,7 +1215,7 @@ bool wxSystemColourProperty::OnEvent( wxPropertyGrid* propgrid, int index = cb->GetSelection(); if ( index == GetCustomColourIndex() && - !(m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) ) + !(m_flags & wxPGPropertyFlags_HideCustomColour) ) askColour = true; } } @@ -1249,7 +1241,7 @@ public: dc.SetPen(*wxBLACK_PEN); if ( item >= 0 && - ( item < (int)(GetCustomColourIndex) || (prop->HasFlag(wxPG_PROP_HIDE_CUSTOM_COLOUR))) + ( item < (int)(GetCustomColourIndex) || (prop->HasFlag(wxPGPropertyFlags_HideCustomColour))) ) { int colInd; @@ -1297,7 +1289,7 @@ void wxSystemColourProperty::OnCustomPaint( wxDC& dc, const wxRect& rect, if ( paintdata.m_choiceItem >= 0 && paintdata.m_choiceItem < (int)m_choices.GetCount() && (paintdata.m_choiceItem != GetCustomColourIndex() || - m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) ) + !!(m_flags & wxPGPropertyFlags_HideCustomColour)) ) { int colInd = m_choices[paintdata.m_choiceItem].GetValue(); col = GetColour( colInd ); @@ -1396,7 +1388,7 @@ bool wxSystemColourProperty::StringToValue( wxVariant& value, const wxString& te } if ( !conversionSuccess && m_choices.GetCount() && - !(m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) && + !(m_flags & wxPGPropertyFlags_HideCustomColour) && isCustomColour ) { if ( !(argFlags & wxPG_EDITABLE_VALUE )) @@ -1463,24 +1455,24 @@ bool wxSystemColourProperty::DoSetAttribute( const wxString& name, wxVariant& va { bool allow = value.GetBool(); - if ( allow && (m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) ) + if ( allow && !!(m_flags & wxPGPropertyFlags_HideCustomColour) ) { // Show custom choice /* TRANSLATORS: Custom colour choice entry */ m_choices.Add(_("Custom"), wxPG_COLOUR_CUSTOM); - m_flags &= ~(wxPG_PROP_HIDE_CUSTOM_COLOUR); + m_flags &= ~(wxPGPropertyFlags_HideCustomColour); } - else if ( !allow && !(m_flags & wxPG_PROP_HIDE_CUSTOM_COLOUR) ) + else if ( !allow && !(m_flags & wxPGPropertyFlags_HideCustomColour) ) { // Hide custom choice m_choices.RemoveAt(GetCustomColourIndex()); - m_flags |= wxPG_PROP_HIDE_CUSTOM_COLOUR; + m_flags |= wxPGPropertyFlags_HideCustomColour; } return true; } else if ( name == wxPG_COLOUR_HAS_ALPHA ) { - ChangeFlag(wxPG_PROP_COLOUR_HAS_ALPHA, value.GetBool()); + ChangeFlag(wxPGPropertyFlags_ColourHasAlpha, value.GetBool()); return true; } return wxEnumProperty::DoSetAttribute(name, value); @@ -1594,7 +1586,7 @@ wxColourProperty::wxColourProperty( const wxString& label, Init( value ); - m_flags |= wxPG_PROP_TRANSLATE_CUSTOM; + m_flags |= wxPGPropertyFlags_TranslateCustom; } void wxColourProperty::Init( wxColour colour ) @@ -1716,7 +1708,7 @@ wxCursorProperty::wxCursorProperty( const wxString& label, const wxString& name, &gs_wxCursorProperty_choicesCache, value ) { - m_flags |= wxPG_PROP_STATIC_CHOICES; // Cursor selection cannot be changed. + m_flags |= wxPGPropertyFlags_StaticChoices; // Cursor selection cannot be changed. } wxString wxCursorProperty::ValueToString(wxVariant& value, int argFlags) const diff --git a/src/propgrid/editors.cpp b/src/propgrid/editors.cpp index b7ba31714e..de9f230bf3 100644 --- a/src/propgrid/editors.cpp +++ b/src/propgrid/editors.cpp @@ -192,7 +192,7 @@ void wxPGEditor::SetControlAppearance( wxPropertyGrid* pg, else if ( oCell.HasText() ) { tcText = property->GetValueAsString( - property->HasFlag(wxPG_PROP_READONLY)?0:wxPG_EDITABLE_VALUE); + property->HasFlag(wxPGPropertyFlags::ReadOnly)?0:wxPG_EDITABLE_VALUE); changeText = true; } @@ -280,18 +280,18 @@ wxPGWindowList wxPGTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid, // // If has children, and limited editing is specified, then don't create. - if ( property->HasFlag(wxPG_PROP_NOEDITOR) && + if ( property->HasFlag(wxPGPropertyFlags::NoEditor) && property->HasAnyChild() ) return nullptr; int argFlags = 0; - if ( !property->HasFlag(wxPG_PROP_READONLY) && + if ( !property->HasFlag(wxPGPropertyFlags::ReadOnly) && !property->IsValueUnspecified() ) argFlags |= wxPG_EDITABLE_VALUE; text = property->GetValueAsString(argFlags); int flags = 0; - if ( property->HasFlag(wxPG_PROP_PASSWORD) && + if ( property->HasFlag(wxPGPropertyFlags_Password) && wxDynamicCast(property, wxStringProperty) ) flags |= wxTE_PASSWORD; @@ -310,7 +310,7 @@ void wxPGTextCtrlEditor::DrawValue( wxDC& dc, wxPGProperty* property, const wxRe // Code below should no longer be needed, as the obfuscation // is now done in GetValueAsString. - /*if ( property->HasFlag(wxPG_PROP_PASSWORD) && + /*if ( property->HasFlag(wxPGPropertyFlags_Password) && wxDynamicCast(property, wxStringProperty) ) { size_t a = drawStr.length(); @@ -435,7 +435,7 @@ void wxPGTextCtrlEditor_OnFocus( wxPGProperty* property, { // Make sure there is correct text (instead of unspecified value // indicator or hint text) - int flags = property->HasFlag(wxPG_PROP_READONLY) ? + int flags = property->HasFlag(wxPGPropertyFlags::ReadOnly) ? 0 : wxPG_EDITABLE_VALUE; wxString correctText = property->GetValueAsString(flags); @@ -494,7 +494,7 @@ protected: wxMilliClock_t t = ::wxGetLocalTimeMillis(); wxEventType evtType = event.GetEventType(); - if ( m_property->HasFlag(wxPG_PROP_USE_DCC) && + if ( m_property->HasFlag(wxPGPropertyFlags_UseDCC) && !m_combo->IsPopupShown() ) { // Just check that it is in the text area @@ -799,11 +799,11 @@ void wxPropertyGrid::OnComboItemPaint( const wxPGComboBox* pCb, { renderFlags |= wxPGCellRenderer::Control; - // If wxPG_PROP_CUSTOMIMAGE was set, then that means any custom + // If wxPGPropertyFlags::CustomImage was set, then that means any custom // image will not appear on the control row (it may be too // large to fit, for instance). Also do not draw custom image // if no choice was selected. - if ( !p->HasFlag(wxPG_PROP_CUSTOMIMAGE) ) + if ( !p->HasFlag(wxPGPropertyFlags::CustomImage) ) useCustomPaintProcedure = false; } else @@ -941,7 +941,7 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid, // Since it is not possible (yet) to create a read-only combo box in // the same sense that wxTextCtrl is read-only, simply do not create // the control in this case. - if ( property->HasFlag(wxPG_PROP_READONLY) ) + if ( property->HasFlag(wxPGPropertyFlags::ReadOnly) ) return nullptr; const wxPGChoices& choices = property->GetChoices(); @@ -949,7 +949,7 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid, int index = property->GetChoiceSelection(); int argFlags = 0; - if ( !property->HasFlag(wxPG_PROP_READONLY) && + if ( !property->HasFlag(wxPGPropertyFlags::ReadOnly) && !property->IsValueUnspecified() ) argFlags |= wxPG_EDITABLE_VALUE; defString = property->GetValueAsString(argFlags); @@ -967,7 +967,7 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid, int odcbFlags = extraStyle | wxBORDER_NONE | wxTE_PROCESS_ENTER; - if ( property->HasFlag(wxPG_PROP_USE_DCC) && + if ( property->HasFlag(wxPGPropertyFlags_UseDCC) && wxDynamicCast(property, wxBoolProperty) ) odcbFlags |= wxODCB_DCLICK_CYCLES; @@ -1343,7 +1343,7 @@ wxPGWindowList wxPGTextCtrlAndButtonEditor::CreateControls( wxPropertyGrid* prop { wxWindow* wnd2; wxWindow* wnd = propGrid->GenerateEditorTextCtrlAndButton( pos, sz, &wnd2, - property->HasFlag(wxPG_PROP_NOEDITOR), property); + property->HasFlag(wxPGPropertyFlags::NoEditor), property); return wxPGWindowList(wnd, wnd2); } @@ -1627,7 +1627,7 @@ wxPGWindowList wxPGCheckBoxEditor::CreateControls( wxPropertyGrid* propGrid, const wxPoint& pos, const wxSize& size ) const { - if ( property->HasFlag(wxPG_PROP_READONLY) ) + if ( property->HasFlag(wxPGPropertyFlags::ReadOnly) ) return nullptr; wxPoint pt = pos; @@ -1899,7 +1899,7 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos, int tcFlags = wxTE_PROCESS_ENTER | extraStyle; - if ( prop->HasFlag(wxPG_PROP_READONLY) && forColumn == 1 ) + if ( prop->HasFlag(wxPGPropertyFlags::ReadOnly) && forColumn == 1 ) tcFlags |= wxTE_READONLY; wxPoint p(pos); @@ -1952,7 +1952,7 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrl( const wxPoint& pos, // This code is repeated from DoSelectProperty(). However, font boldness // must be set before margin is set up below in FixPosForTextCtrl(). if ( forColumn == 1 && - prop->HasFlag(wxPG_PROP_MODIFIED) && + prop->HasFlag(wxPGPropertyFlags::Modified) && HasFlag(wxPG_BOLD_MODIFIED) ) tc->SetFont( m_captionFont ); @@ -2019,7 +2019,7 @@ wxWindow* wxPropertyGrid::GenerateEditorButton( const wxPoint& pos, const wxSize p.x = pos.x + sz.x - s.x; but->Move(p); - if ( selected->HasFlag(wxPG_PROP_READONLY) && !selected->HasFlag(wxPG_PROP_ACTIVE_BTN) ) + if ( selected->HasFlag(wxPGPropertyFlags::ReadOnly) && !selected->HasFlag(wxPGPropertyFlags_ActiveButton) ) but->Disable(); return but; @@ -2048,7 +2048,7 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrlAndButton( const wxPoint& pos, wxString text; if ( !property->IsValueUnspecified() ) - text = property->GetValueAsString(property->HasFlag(wxPG_PROP_READONLY)?0:wxPG_EDITABLE_VALUE); + text = property->GetValueAsString(property->HasFlag(wxPGPropertyFlags::ReadOnly)?0:wxPG_EDITABLE_VALUE); return GenerateEditorTextCtrl(pos, sz, text, but, 0, property->GetMaxLength()); } diff --git a/src/propgrid/property.cpp b/src/propgrid/property.cpp index d7cc69f623..a78d89d078 100644 --- a/src/propgrid/property.cpp +++ b/src/propgrid/property.cpp @@ -582,7 +582,7 @@ void wxPGProperty::Init() m_maxLen = 0; // infinite maximum length - m_flags = wxPG_PROP_PROPERTY; + m_flags = wxPGPropertyFlags::Property; m_depth = 1; @@ -634,24 +634,24 @@ void wxPGProperty::InitAfterAdded( wxPropertyGridPageState* pageState, // If in hideable adding mode, or if assigned parent is hideable, then // make this one hideable. if ( - ( !parentIsRoot && parent->HasFlag(wxPG_PROP_HIDDEN) ) || + ( !parentIsRoot && parent->HasFlag(wxPGPropertyFlags::Hidden) ) || ( propgrid && (propgrid->HasInternalFlag(wxPropertyGrid::wxPG_FL_ADDING_HIDEABLES)) ) ) - SetFlag( wxPG_PROP_HIDDEN ); + SetFlag(wxPGPropertyFlags::Hidden); // Set custom image flag. int custImgHeight = OnMeasureImage().y; if ( custImgHeight == wxDefaultCoord ) { - SetFlag(wxPG_PROP_CUSTOMIMAGE); + SetFlag(wxPGPropertyFlags::CustomImage); } if ( propgrid && (propgrid->HasFlag(wxPG_LIMITED_EDITING)) ) - SetFlag(wxPG_PROP_NOEDITOR); + SetFlag(wxPGPropertyFlags::NoEditor); // Make sure parent has some parental flags - if ( !parent->HasFlag(wxPG_PROP_PARENTAL_FLAGS) ) - parent->SetParentalType(wxPG_PROP_MISC_PARENT); + if ( !parent->HasFlag(wxPGPropertyFlags::ParentalFlags) ) + parent->SetParentalType(wxPGPropertyFlags::MiscParent); if ( !IsCategory() ) { @@ -707,14 +707,14 @@ void wxPGProperty::InitAfterAdded( wxPropertyGridPageState* pageState, if ( HasAnyChild() ) { // Check parental flags - wxASSERT_MSG( ((m_flags & wxPG_PROP_PARENTAL_FLAGS) == - wxPG_PROP_AGGREGATE) || - ((m_flags & wxPG_PROP_PARENTAL_FLAGS) == - wxPG_PROP_MISC_PARENT), + wxASSERT_MSG( ((m_flags & wxPGPropertyFlags::ParentalFlags) == + wxPGPropertyFlags::Aggregate) || + ((m_flags & wxPGPropertyFlags::ParentalFlags) == + wxPGPropertyFlags::MiscParent), wxS("wxPGProperty parental flags set incorrectly at ") wxS("this time") ); - if ( HasFlag(wxPG_PROP_AGGREGATE) ) + if ( HasFlag(wxPGPropertyFlags::Aggregate) ) { // Properties with private children are not expanded by default. SetExpanded(false); @@ -734,7 +734,7 @@ void wxPGProperty::InitAfterAdded( wxPropertyGridPageState* pageState, } if ( propgrid && propgrid->HasExtraStyle(wxPG_EX_AUTO_UNSPECIFIED_VALUES) ) - SetFlagRecursively(wxPG_PROP_AUTO_UNSPECIFIED, true); + SetFlagRecursively(wxPGPropertyFlags::AutoUnspecified, true); } } @@ -1042,7 +1042,7 @@ void wxPGProperty::DoGenerateComposedValue( wxString& text, if ( !childValue.IsNull() ) { if ( overridesLeft && - curChild->HasFlag(wxPG_PROP_COMPOSED_VALUE) && + curChild->HasFlag(wxPGPropertyFlags::ComposedValue) && childValue.IsType(wxPG_VARIANT_TYPE_LIST) ) { wxVariantList& childList = childValue.GetList(); @@ -1217,8 +1217,8 @@ bool wxPGProperty::StringToValue( wxVariant& v, const wxString& text, int argFla // Add only if editable or setting programmatically if ( (argFlags & wxPG_PROGRAMMATIC_VALUE) || - (!child->HasFlag(wxPG_PROP_DISABLED) && - !child->HasFlag(wxPG_PROP_READONLY)) ) + (!child->HasFlag(wxPGPropertyFlags::Disabled) && + !child->HasFlag(wxPGPropertyFlags::ReadOnly)) ) { if ( len > 0 ) { @@ -1296,8 +1296,8 @@ bool wxPGProperty::StringToValue( wxVariant& v, const wxString& text, int argFla wxVariant variant(oldChildValue); if ( (argFlags & wxPG_PROGRAMMATIC_VALUE) || - (!child->HasFlag(wxPG_PROP_DISABLED) && - !child->HasFlag(wxPG_PROP_READONLY)) ) + (!child->HasFlag(wxPGPropertyFlags::Disabled) && + !child->HasFlag(wxPGPropertyFlags::ReadOnly)) ) { wxString childName = child->GetBaseName(); @@ -1474,7 +1474,7 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, wxPGSetValueFlag { // // However, situation is different for composed string properties - if ( HasFlag(wxPG_PROP_COMPOSED_VALUE) ) + if ( HasFlag(wxPGPropertyFlags::ComposedValue) ) { tempListVariant = value; pList = &tempListVariant; @@ -1486,7 +1486,7 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, wxPGSetValueFlag //wxLogDebug(wxS(">> %s.SetValue() adapted list value to type '%s'"),GetName(),value.GetType()); } - if ( HasFlag( wxPG_PROP_AGGREGATE) ) + if ( HasFlag(wxPGPropertyFlags::Aggregate) ) flags |= wxPGSetValueFlags::Aggregated; if ( pList && !pList->IsNull() ) @@ -1511,7 +1511,7 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, wxPGSetValueFlag //wxLogDebug(wxS("%i: child = %s, childValue.GetType()=%s"),i,child->GetBaseName(),childValue.GetType()); if ( childValue.IsType(wxPG_VARIANT_TYPE_LIST) ) { - if ( child->HasFlag(wxPG_PROP_AGGREGATE) && !(flags & wxPGSetValueFlags::Aggregated) ) + if ( child->HasFlag(wxPGPropertyFlags::Aggregate) && !(flags & wxPGSetValueFlags::Aggregated) ) { wxVariant listRefCopy = childValue; child->SetValue(childValue, &listRefCopy, flags| wxPGSetValueFlags::FromParent); @@ -1526,10 +1526,10 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, wxPGSetValueFlag { // For aggregate properties, we will trust RefreshChildren() // to update child values. - if ( !HasFlag(wxPG_PROP_AGGREGATE) ) + if ( !HasFlag(wxPGPropertyFlags::Aggregate) ) child->SetValue(childValue, nullptr, flags| wxPGSetValueFlags::FromParent); if ( !!(flags & wxPGSetValueFlags::ByUser) ) - child->SetFlag(wxPG_PROP_MODIFIED); + child->SetFlag(wxPGPropertyFlags::Modified); } } i++; @@ -1549,9 +1549,9 @@ void wxPGProperty::SetValue( wxVariant value, wxVariant* pList, wxPGSetValueFlag } if ( !!(flags & wxPGSetValueFlags::ByUser) ) - SetFlag(wxPG_PROP_MODIFIED); + SetFlag(wxPGPropertyFlags::Modified); - if ( HasFlag(wxPG_PROP_AGGREGATE) ) + if ( HasFlag(wxPGPropertyFlags::Aggregate) ) RefreshChildren(); } else @@ -1683,7 +1683,7 @@ void wxPGProperty::Enable( bool enable ) void wxPGProperty::DoEnable( bool enable ) { - ChangeFlag(wxPG_PROP_DISABLED, !enable); + ChangeFlag(wxPGPropertyFlags::Disabled, !enable); // Apply same to sub-properties as well for ( wxPGProperty* child : m_children ) @@ -1722,7 +1722,7 @@ void wxPGProperty::AdaptiveSetCell( unsigned int firstCol, const wxPGCell& cell, const wxPGCell& srcData, wxPGCellData* unmodCellData, - FlagType ignoreWithFlags, + wxPGPropertyFlags ignoreWithFlags, bool recursively ) { // @@ -1764,7 +1764,7 @@ void wxPGProperty::AdaptiveSetCell( unsigned int firstCol, } } -void wxPGProperty::ClearCells(FlagType ignoreWithFlags, bool recursively) +void wxPGProperty::ClearCells(wxPGPropertyFlags ignoreWithFlags, bool recursively) { if ( !(m_flags & ignoreWithFlags) && !IsRoot() ) { @@ -1835,7 +1835,7 @@ void wxPGProperty::SetBackgroundColour(const wxColour& colour, wxPGPropertyValue newCell, srcCell, firstCellData, - recursively ? wxPG_PROP_CATEGORY : 0, + recursively ? wxPGPropertyFlags::Category : wxPGPropertyFlags::Null, recursively ); } @@ -1870,7 +1870,7 @@ void wxPGProperty::SetTextColour(const wxColour& colour, wxPGPropertyValuesFlags newCell, srcCell, firstCellData, - recursively ? wxPG_PROP_CATEGORY : 0, + recursively ? wxPGPropertyFlags::Category : wxPGPropertyFlags::Null, recursively ); } @@ -1891,7 +1891,7 @@ void wxPGProperty::SetDefaultColours(wxPGPropertyValuesFlags flags) } } - ClearCells(recursively ? wxPG_PROP_CATEGORY : 0, + ClearCells(recursively ? wxPGPropertyFlags::Category : wxPGPropertyFlags::Null, recursively); } @@ -1980,22 +1980,22 @@ wxVariant wxPGProperty::GetAttributesAsList() const // Utility flags are excluded. // Store the literals in the internal representation for better performance. -static const std::array, 4> gs_propFlagToString +static const std::array, 4> gs_propFlagToString { { - { wxPG_PROP_DISABLED, wxS("DISABLED") }, - { wxPG_PROP_HIDDEN, wxS("HIDDEN") }, - { wxPG_PROP_NOEDITOR, wxS("NOEDITOR") }, - { wxPG_PROP_COLLAPSED, wxS("COLLAPSED") } + { wxPGPropertyFlags::Disabled, wxS("DISABLED") }, + { wxPGPropertyFlags::Hidden, wxS("HIDDEN") }, + { wxPGPropertyFlags::NoEditor, wxS("NOEDITOR") }, + { wxPGPropertyFlags::Collapsed, wxS("COLLAPSED") } } }; -wxString wxPGProperty::GetFlagsAsString( FlagType flagsMask ) const +wxString wxPGProperty::GetFlagsAsString(wxPGPropertyFlags flagsMask) const { wxString s; - const FlagType relevantFlags = m_flags & flagsMask & wxPG_STRING_STORED_FLAGS; + const wxPGPropertyFlags relevantFlags = m_flags & flagsMask & wxPGPropertyFlags::StringStoredFlags; for ( auto& item : gs_propFlagToString ) { - if ( relevantFlags & item.first ) + if ( !!(relevantFlags & item.first) ) { if ( !s.empty() ) { @@ -2010,7 +2010,7 @@ wxString wxPGProperty::GetFlagsAsString( FlagType flagsMask ) const void wxPGProperty::SetFlagsFromString( const wxString& str ) { - FlagType flags = 0; + wxPGPropertyFlags flags = wxPGPropertyFlags::Null; WX_PG_TOKENIZER1_BEGIN(str, wxS('|')) for ( auto& item : gs_propFlagToString ) @@ -2023,7 +2023,7 @@ void wxPGProperty::SetFlagsFromString( const wxString& str ) } WX_PG_TOKENIZER1_END() - m_flags = (m_flags & ~wxPG_STRING_STORED_FLAGS) | flags; + m_flags = (m_flags & ~wxPGPropertyFlags::StringStoredFlags) | flags; } wxValidator* wxPGProperty::DoGetValidator() const @@ -2195,7 +2195,7 @@ bool wxPGProperty::Hide( bool hide, wxPGPropertyValuesFlags flags ) bool wxPGProperty::DoHide( bool hide, wxPGPropertyValuesFlags flags ) { - ChangeFlag(wxPG_PROP_HIDDEN, hide); + ChangeFlag(wxPGPropertyFlags::Hidden, hide); if ( !!(flags & wxPGPropertyValuesFlags::Recurse) ) { @@ -2210,7 +2210,7 @@ bool wxPGProperty::HasVisibleChildren() const { for ( wxPGProperty* child : m_children ) { - if ( !child->HasFlag(wxPG_PROP_HIDDEN) ) + if ( !child->HasFlag(wxPGPropertyFlags::Hidden) ) return true; } @@ -2240,12 +2240,12 @@ void wxPGProperty::SetValueImage( const wxBitmapBundle& bmp ) if ( bmp.IsOk() ) { m_valueBitmapBundle = bmp; - m_flags |= wxPG_PROP_CUSTOMIMAGE; + m_flags |= wxPGPropertyFlags::CustomImage; } else { m_valueBitmapBundle = wxBitmapBundle(); - m_flags &= ~(wxPG_PROP_CUSTOMIMAGE); + m_flags &= ~(wxPGPropertyFlags::CustomImage); } } @@ -2278,12 +2278,12 @@ const wxPGProperty* wxPGProperty::GetLastVisibleSubItem() const bool wxPGProperty::IsVisible() const { - if ( HasFlag(wxPG_PROP_HIDDEN) ) + if ( HasFlag(wxPGPropertyFlags::Hidden) ) return false; for (const wxPGProperty* parent = GetParent(); parent != nullptr; parent = parent->GetParent() ) { - if ( !parent->IsExpanded() || parent->HasFlag(wxPG_PROP_HIDDEN) ) + if ( !parent->IsExpanded() || parent->HasFlag(wxPGPropertyFlags::Hidden) ) return false; } @@ -2359,18 +2359,17 @@ void wxPGProperty::DoPreAddChild( int index, wxPGProperty* prop ) int custImgHeight = prop->OnMeasureImage().y; if ( custImgHeight == wxDefaultCoord /*|| custImgHeight > 1*/ ) - prop->m_flags |= wxPG_PROP_CUSTOMIMAGE; + prop->m_flags |= wxPGPropertyFlags::CustomImage; prop->m_parent = this; } void wxPGProperty::AddPrivateChild( wxPGProperty* prop ) { - if ( !(m_flags & wxPG_PROP_PARENTAL_FLAGS) ) - SetParentalType(wxPG_PROP_AGGREGATE); + if ( !(m_flags & wxPGPropertyFlags::ParentalFlags) ) + SetParentalType(wxPGPropertyFlags::Aggregate); - wxASSERT_MSG( (m_flags & wxPG_PROP_PARENTAL_FLAGS) == - wxPG_PROP_AGGREGATE, + wxASSERT_MSG( (m_flags & wxPGPropertyFlags::ParentalFlags) == wxPGPropertyFlags::Aggregate, wxS("Do not mix up AddPrivateChild() calls with other ") wxS("property adders.") ); @@ -2389,11 +2388,10 @@ wxPGProperty* wxPGProperty::InsertChild( int index, } else { - if ( !(m_flags & wxPG_PROP_PARENTAL_FLAGS) ) - SetParentalType(wxPG_PROP_MISC_PARENT); + if ( !(m_flags & wxPGPropertyFlags::ParentalFlags) ) + SetParentalType(wxPGPropertyFlags::MiscParent); - wxASSERT_MSG( (m_flags & wxPG_PROP_PARENTAL_FLAGS) == - wxPG_PROP_MISC_PARENT, + wxASSERT_MSG( (m_flags & wxPGPropertyFlags::ParentalFlags) == wxPGPropertyFlags::MiscParent, wxS("Do not mix up AddPrivateChild() calls with other ") wxS("property adders.") ); @@ -2446,7 +2444,7 @@ void wxPGProperty::AdaptListToValue( wxVariant& list, wxVariant* value ) const // Don't fully update aggregate properties unless all children have // specified value - if ( HasFlag(wxPG_PROP_AGGREGATE) ) + if ( HasFlag(wxPGPropertyFlags::Aggregate) ) allChildrenSpecified = AreAllChildrenSpecified(&list); else allChildrenSpecified = true; @@ -2557,7 +2555,7 @@ int wxPGProperty::GetChildrenHeight( int lh, int iMax ) const { wxPGProperty* pwc = Item(i); - if ( !pwc->HasFlag(wxPG_PROP_HIDDEN) ) + if ( !pwc->HasFlag(wxPGPropertyFlags::Hidden) ) { if ( !pwc->IsExpanded() || !pwc->HasAnyChild() ) @@ -2585,7 +2583,7 @@ wxPGProperty* wxPGProperty::GetItemAtY( unsigned int y, for ( wxPGProperty* pwc : m_children ) { - if ( !pwc->HasFlag(wxPG_PROP_HIDDEN) ) + if ( !pwc->HasFlag(wxPGPropertyFlags::Hidden) ) { // Found? if ( y < iy ) @@ -2630,7 +2628,7 @@ wxPGProperty* wxPGProperty::GetItemAtY( unsigned int y, void wxPGProperty::Empty() { - if ( !HasFlag(wxPG_PROP_CHILDREN_ARE_COPIES) ) + if ( !HasFlag(wxPGPropertyFlags::ChildrenAreCopies) ) { for ( wxPGProperty* child : m_children ) { @@ -2748,7 +2746,7 @@ bool wxPGProperty::AreAllChildrenSpecified( const wxVariant* pendingList ) const wxPGProperty* wxPGProperty::UpdateParentValues() { wxPGProperty* parent = m_parent; - if ( parent && parent->HasFlag(wxPG_PROP_COMPOSED_VALUE) && + if ( parent && parent->HasFlag(wxPGPropertyFlags::ComposedValue) && !parent->IsCategory() && !parent->IsRoot() ) { wxString s; @@ -2761,10 +2759,10 @@ wxPGProperty* wxPGProperty::UpdateParentValues() bool wxPGProperty::IsTextEditable() const { - if ( HasFlag(wxPG_PROP_READONLY) ) + if ( HasFlag(wxPGPropertyFlags::ReadOnly) ) return false; - if ( HasFlag(wxPG_PROP_NOEDITOR) && + if ( HasFlag(wxPGPropertyFlags::NoEditor) && (HasAnyChild() || wxString(GetEditorClass()->GetClassInfo()->GetClassName()).EndsWith(wxS("Button"))) ) @@ -2816,7 +2814,7 @@ wxString wxPGProperty::GetHintText() const int wxPGProperty::GetDisplayedCommonValueCount() const { - if ( HasFlag(wxPG_PROP_USES_COMMON_VALUE) ) + if ( HasFlag(wxPGPropertyFlags::UsesCommonValue) ) { wxPropertyGrid* pg = GetGrid(); if ( pg ) @@ -2871,7 +2869,7 @@ wxPGRootProperty::wxPGRootProperty( const wxString& name ) { m_name = name; m_label = m_name; - SetParentalType(0); + SetParentalType(wxPGPropertyFlags::Null); m_depth = 0; } @@ -2884,7 +2882,7 @@ wxPG_IMPLEMENT_PROPERTY_CLASS(wxPropertyCategory, wxPGProperty, TextCtrl) void wxPropertyCategory::Init() { // don't set colour - prepareadditem method should do this - SetParentalType(wxPG_PROP_CATEGORY); + SetParentalType(wxPGPropertyFlags::Category); m_capFgColIndex = 1; m_textExtent = -1; } diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 0d38410cb7..3ea759876c 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -943,11 +943,11 @@ void wxPropertyGrid::MakeColumnEditable( unsigned int column, bool editable ) { // The second column is always editable. To make it read-only is a property - // by property decision by setting its wxPG_PROP_READONLY flag. + // by property decision by setting its wxPGPropertyFlags::ReadOnly flag. wxASSERT_MSG ( column != 1, - wxS("Set wxPG_PROP_READONLY property flag instead") + wxS("Set wxPGPropertyFlags::ReadOnly property flag instead") ); if ( editable ) @@ -2158,7 +2158,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, { const wxPGProperty* p = *it; - if ( !p->HasFlag(wxPG_PROP_HIDDEN) ) + if ( !p->HasFlag(wxPGPropertyFlags::Hidden) ) { visPropArray.push_back(const_cast(p)); @@ -2365,7 +2365,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, if ( butRect.x > 0 ) butRect.x += IN_CELL_EXPANDER_BUTTON_X_ADJUST; - if ( p->HasFlag(wxPG_PROP_MODIFIED) && + if ( p->HasFlag(wxPGPropertyFlags::Modified) && (windowStyle & wxPG_BOLD_MODIFIED) ) { dc.SetFont(m_captionFont); @@ -3000,7 +3000,7 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue wxVariant* pPendingValue = &pendingValue; wxVariant* pList = nullptr; - // If parent has wxPG_PROP_AGGREGATE flag, or uses composite + // If parent has wxPGPropertyFlags::Aggregate flag, or uses composite // string value, then we need treat as it was changed instead // (or, in addition, as is the case with composite string parent). // This includes creating list variant for child values. @@ -3014,7 +3014,7 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue listValue.SetName(p->GetBaseName()); while ( pwc && - (pwc->HasFlag(wxPG_PROP_AGGREGATE) || pwc->HasFlag(wxPG_PROP_COMPOSED_VALUE)) ) + (pwc->HasFlag(wxPGPropertyFlags::Aggregate) || pwc->HasFlag(wxPGPropertyFlags::ComposedValue)) ) { wxVariantList tempList; wxVariant lv(tempList, pwc->GetBaseName()); @@ -3022,7 +3022,7 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue listValue = lv; pPendingValue = &listValue; - if ( pwc->HasFlag(wxPG_PROP_AGGREGATE) ) + if ( pwc->HasFlag(wxPGPropertyFlags::Aggregate) ) { baseChangedProperty = pwc; bcpPendingList = lv; @@ -3052,9 +3052,9 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue { // FIXME: After proper ValueToString()s added, remove // this. It is just a temporary fix, as evt_changing - // will simply not work for wxPG_PROP_COMPOSED_VALUE + // will simply not work for wxPGPropertyFlags::ComposedValue // (unless it is selected, and textctrl editor is open). - if ( changedProperty->HasFlag(wxPG_PROP_COMPOSED_VALUE) ) + if ( changedProperty->HasFlag(wxPGPropertyFlags::ComposedValue) ) { evtChangingProperty = baseChangedProperty; if ( evtChangingProperty != p ) @@ -3067,7 +3067,7 @@ bool wxPropertyGrid::PerformValidation( wxPGProperty* p, wxVariant& pendingValue } } - if ( evtChangingProperty->HasFlag(wxPG_PROP_COMPOSED_VALUE) ) + if ( evtChangingProperty->HasFlag(wxPGPropertyFlags::ComposedValue) ) { if ( changedProperty == GetSelection() ) { @@ -3194,7 +3194,7 @@ bool wxPropertyGrid::OnValidationFailure( wxPGProperty* property, { // When property selection is being changed, do not display any // messages, if some were already shown for this property. - if ( property->HasFlag(wxPG_PROP_INVALID_VALUE) ) + if ( property->HasFlag(wxPGPropertyFlags::InvalidValue) ) { m_validationInfo.SetFailureBehavior( vfb & (~(wxPGVFBFlags::ShowMessage | @@ -3216,7 +3216,7 @@ bool wxPropertyGrid::OnValidationFailure( wxPGProperty* property, property->GetEditorClass()->UpdateControl(property, editor); } - property->SetFlag(wxPG_PROP_INVALID_VALUE); + property->SetFlag(wxPGPropertyFlags::InvalidValue); return res; } @@ -3229,7 +3229,7 @@ bool wxPropertyGrid::DoOnValidationFailure( wxPGProperty* property, wxVariant& W ::wxBell(); if ( !!(vfb & wxPGVFBFlags::MarkCell) && - !property->HasFlag(wxPG_PROP_INVALID_VALUE) ) + !property->HasFlag(wxPGPropertyFlags::InvalidValue) ) { unsigned int colCount = m_pState->GetColumnCount(); @@ -3381,9 +3381,9 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, wxPGSelectPropertyFlags wxWindow* editor = GetEditorControl(); // Set as Modified (not if dragging just began) - if ( !p->HasFlag(wxPG_PROP_MODIFIED) ) + if ( !p->HasFlag(wxPGPropertyFlags::Modified) ) { - p->SetFlag(wxPG_PROP_MODIFIED); + p->SetFlag(wxPGPropertyFlags::Modified); if ( p == selected && (m_windowStyle & wxPG_BOLD_MODIFIED) ) { if ( editor ) @@ -3398,7 +3398,7 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, wxPGSelectPropertyFlags while ( prevPwc != topPaintedProperty ) { - pwc->SetFlag(wxPG_PROP_MODIFIED); + pwc->SetFlag(wxPGPropertyFlags::Modified); if ( pwc == selected && (m_windowStyle & wxPG_BOLD_MODIFIED) ) { @@ -3429,11 +3429,11 @@ bool wxPropertyGrid::DoPropertyChanged( wxPGProperty* p, wxPGSelectPropertyFlags } // Sanity check - wxASSERT( !changedProperty->GetParent()->HasFlag(wxPG_PROP_AGGREGATE) ); + wxASSERT( !changedProperty->GetParent()->HasFlag(wxPGPropertyFlags::Aggregate) ); // If top parent has composite string value, then send to child parents, // starting from baseChangedProperty. - if ( changedProperty->HasFlag(wxPG_PROP_COMPOSED_VALUE) ) + if ( changedProperty->HasFlag(wxPGPropertyFlags::ComposedValue) ) { pwc = m_chgInfo_baseChangedProperty; @@ -3556,7 +3556,7 @@ bool wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) // Somehow, event is handled after property has been deselected. // Possibly, but very rare. if ( !selected || - selected->HasFlag(wxPG_PROP_BEING_DELETED) || + selected->HasFlag(wxPGPropertyFlags::BeingDeleted) || m_inOnValidationFailure || // Also don't handle editor event if wxEVT_PG_CHANGED or // similar is currently doing something (showing a @@ -4036,7 +4036,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, wxPGSelectPropertyFlags prevFirstSel = prevSelection.empty()? nullptr: prevSelection[0]; - if ( prevFirstSel && prevFirstSel->HasFlag(wxPG_PROP_BEING_DELETED) ) + if ( prevFirstSel && prevFirstSel->HasFlag(wxPGPropertyFlags::BeingDeleted) ) prevFirstSel = nullptr; // Always send event, as this is indirect call @@ -4150,7 +4150,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, wxPGSelectPropertyFlags // // Only create editor for non-disabled non-caption - if ( !p->IsCategory() && !p->HasFlag(wxPG_PROP_DISABLED) ) + if ( !p->IsCategory() && !p->HasFlag(wxPGPropertyFlags::Disabled) ) { // do this for non-caption items @@ -4158,7 +4158,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, wxPGSelectPropertyFlags // Do we need to paint the custom image, if any? m_iFlags &= ~(wxPG_FL_CUR_USES_CUSTOM_IMAGE); - if ( p->HasFlag(wxPG_PROP_CUSTOMIMAGE) && + if ( p->HasFlag(wxPGPropertyFlags::CustomImage) && !p->GetEditorClass()->CanContainCustomImage() ) m_iFlags |= wxPG_FL_CUR_USES_CUSTOM_IMAGE; @@ -4224,7 +4224,7 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, wxPGSelectPropertyFlags // If it has modified status, use bold font // (must be done before capturing m_ctrlXAdjust) - if ( p->HasFlag(wxPG_PROP_MODIFIED) && + if ( p->HasFlag(wxPGPropertyFlags::Modified) && (m_windowStyle & wxPG_BOLD_MODIFIED) ) SetCurControlBoldFont(); // Store x relative to splitter (we'll need it). @@ -4415,7 +4415,7 @@ void wxPropertyGrid::RefreshEditor() // calling UpdateControl(). if ( HasFlag(wxPG_BOLD_MODIFIED) ) { - if ( p->HasFlag(wxPG_PROP_MODIFIED) ) + if ( p->HasFlag(wxPGPropertyFlags::Modified) ) wnd->SetFont(GetCaptionFont()); else wnd->SetFont(GetFont()); @@ -5111,7 +5111,7 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, space -= (wxPG_XBEFORETEXT + 1); int tw, th; const wxFont* font = nullptr; - if ( (m_windowStyle & wxPG_BOLD_MODIFIED) && m_propHover->HasFlag(wxPG_PROP_MODIFIED) ) + if ( (m_windowStyle & wxPG_BOLD_MODIFIED) && m_propHover->HasFlag(wxPGPropertyFlags::Modified) ) font = &m_captionFont; if ( cell.GetFont().IsOk() ) font = &cell.GetFont(); @@ -5183,7 +5183,7 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, // Since categories cannot be selected along with 'other' // properties, exclude them from iterator flags. - int iterFlags = wxPG_ITERATE_VISIBLE & (~wxPG_PROP_CATEGORY); + int iterFlags = wxPG_ITERATE_VISIBLE & (~wxPGPropertyFlags::Category); for ( int i=(selection.size()-1); i>=0; i-- ) { @@ -5730,7 +5730,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) if ( action == wxPGKeyboardActions::Edit && !editorFocused ) { // Mark as handled only for editable property - if ( !p->IsCategory() && p->IsEnabled() && !p->HasFlag(wxPG_PROP_READONLY) ) + if ( !p->IsCategory() && p->IsEnabled() && !p->HasFlag(wxPGPropertyFlags::ReadOnly) ) { DoSelectProperty( p, wxPGSelectPropertyFlags::Focus ); wasHandled = true; @@ -6373,7 +6373,7 @@ wxPGProperty* wxPropertyGridPopulator::Add( const wxString& propClass, wxClassInfo* classInfo = wxClassInfo::FindClass(propClass); wxPGProperty* parent = GetCurParent(); - if ( parent->HasFlag(wxPG_PROP_AGGREGATE) ) + if ( parent->HasFlag(wxPGPropertyFlags::Aggregate) ) { ProcessError(wxString::Format(wxS("new children cannot be added to '%s'"),parent->GetName())); return nullptr; diff --git a/src/propgrid/propgridiface.cpp b/src/propgrid/propgridiface.cpp index 0980fcb86a..fe95145514 100644 --- a/src/propgrid/propgridiface.cpp +++ b/src/propgrid/propgridiface.cpp @@ -125,7 +125,7 @@ wxPGProperty* wxPropertyGridInterface::RemoveProperty( wxPGPropArg id ) { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxNullProperty) - wxCHECK( !p->HasAnyChild() || p->HasFlag(wxPG_PROP_AGGREGATE), + wxCHECK( !p->HasAnyChild() || p->HasFlag(wxPGPropertyFlags::Aggregate), wxNullProperty); wxPropertyGridPageState* state = p->GetParentState(); @@ -228,7 +228,7 @@ bool wxPropertyGridInterface::EnableProperty( wxPGPropArg id, bool enable ) if ( enable ) { - if ( !p->HasFlag(wxPG_PROP_DISABLED) ) + if ( !p->HasFlag(wxPGPropertyFlags::Disabled) ) return false; // If active, Set active Editor. @@ -237,7 +237,7 @@ bool wxPropertyGridInterface::EnableProperty( wxPGPropArg id, bool enable ) } else { - if ( p->HasFlag(wxPG_PROP_DISABLED) ) + if ( p->HasFlag(wxPGPropertyFlags::Disabled) ) return false; // If active, Disable as active Editor. @@ -258,17 +258,17 @@ void wxPropertyGridInterface::SetPropertyReadOnly( wxPGPropArg id, bool set, wxP if ( !!(flags & wxPGPropertyValuesFlags::Recurse) ) { - p->SetFlagRecursively(wxPG_PROP_READONLY, set); + p->SetFlagRecursively(wxPGPropertyFlags::ReadOnly, set); } else { // Do nothing if flag is already set as required. - if ( set && p->HasFlag(wxPG_PROP_READONLY) ) + if ( set && p->HasFlag(wxPGPropertyFlags::ReadOnly) ) return; - if ( !set && !p->HasFlag(wxPG_PROP_READONLY) ) + if ( !set && !p->HasFlag(wxPGPropertyFlags::ReadOnly) ) return; - p->ChangeFlag(wxPG_PROP_READONLY, set); + p->ChangeFlag(wxPGPropertyFlags::ReadOnly, set); } wxPropertyGridPageState* state = p->GetParentState(); @@ -337,7 +337,7 @@ void wxPropertyGridInterface::ClearModifiedStatus() wxPropertyGridPageState* page; while ( (page = GetPageState(pageIndex)) != nullptr ) { - page->DoGetRoot()->SetFlagRecursively(wxPG_PROP_MODIFIED, false); + page->DoGetRoot()->SetFlagRecursively(wxPGPropertyFlags::Modified, false); page->m_anyModified = false; pageIndex++; @@ -456,7 +456,7 @@ void wxPropertyGridInterface::SetPropertyAttributeAll( const wxString& attrName, // ----------------------------------------------------------------------- void wxPropertyGridInterface::GetPropertiesWithFlag( wxArrayPGProperty* targetArr, - wxPGProperty::FlagType flags, + wxPGPropertyFlags flags, bool inverse, int iterFlags ) const { @@ -538,9 +538,9 @@ bool wxPropertyGridInterface::HideProperty(wxPGPropArg id, bool hide, wxPGProper // Do nothing if single property is already hidden/visible as requested. if ( !(flags & wxPGPropertyValuesFlags::Recurse) ) { - if ( hide && p->HasFlag(wxPG_PROP_HIDDEN) ) + if ( hide && p->HasFlag(wxPGPropertyFlags::Hidden) ) return false; - if ( !hide && !p->HasFlag(wxPG_PROP_HIDDEN) ) + if ( !hide && !p->HasFlag(wxPGPropertyFlags::Hidden) ) return false; } @@ -844,9 +844,9 @@ bool wxPropertyGridInterface::ChangePropertyValue( wxPGPropArg id, wxVariant new void wxPropertyGridInterface::BeginAddChildren( wxPGPropArg id ) { wxPG_PROP_ARG_CALL_PROLOG() - wxCHECK_RET( p->HasFlag(wxPG_PROP_AGGREGATE), wxS("only call on properties with fixed children") ); - p->ClearFlag(wxPG_PROP_AGGREGATE); - p->SetFlag(wxPG_PROP_MISC_PARENT); + wxCHECK_RET( p->HasFlag(wxPGPropertyFlags::Aggregate), wxS("only call on properties with fixed children") ); + p->ClearFlag(wxPGPropertyFlags::Aggregate); + p->SetFlag(wxPGPropertyFlags::MiscParent); } // ----------------------------------------------------------------------- @@ -861,9 +861,9 @@ bool wxPropertyGridInterface::EditorValidate() void wxPropertyGridInterface::EndAddChildren( wxPGPropArg id ) { wxPG_PROP_ARG_CALL_PROLOG() - wxCHECK_RET( p->HasFlag(wxPG_PROP_MISC_PARENT), wxS("only call on properties for which BeginAddChildren was called prior") ); - p->ClearFlag(wxPG_PROP_MISC_PARENT); - p->SetFlag(wxPG_PROP_AGGREGATE); + wxCHECK_RET( p->HasFlag(wxPGPropertyFlags::MiscParent), wxS("only call on properties for which BeginAddChildren was called prior") ); + p->ClearFlag(wxPGPropertyFlags::MiscParent); + p->SetFlag(wxPGPropertyFlags::Aggregate); } // ----------------------------------------------------------------------- @@ -952,7 +952,7 @@ wxString wxPropertyGridInterface::SaveEditableState( int includedStates ) const { const wxPGProperty* p = it.GetProperty(); - if ( !p->HasFlag(wxPG_PROP_COLLAPSED) ) + if ( !p->HasFlag(wxPGPropertyFlags::Collapsed) ) result += EscapeDelimiters(p->GetName()); result += wxS(","); diff --git a/src/propgrid/propgridpagestate.cpp b/src/propgrid/propgridpagestate.cpp index 558030f6a7..0b6e430ab7 100644 --- a/src/propgrid/propgridpagestate.cpp +++ b/src/propgrid/propgridpagestate.cpp @@ -226,7 +226,7 @@ void wxPropertyGridPageState::InitNonCatMode() m_abcArray = new wxPGRootProperty(wxS("")); m_abcArray->SetParentState(this); - m_abcArray->SetFlag(wxPG_PROP_CHILDREN_ARE_COPIES); + m_abcArray->SetFlag(wxPGPropertyFlags::ChildrenAreCopies); // Must be called when state::m_properties still points to regularArray. wxPGProperty* oldProperties = m_properties; @@ -402,7 +402,7 @@ wxPGProperty* wxPropertyGridPageState::GetLastItem( int flags ) if ( !m_properties->HasAnyChild() ) return nullptr; - wxPG_ITERATOR_CREATE_MASKS(flags, wxPGProperty::FlagType itemExMask, wxPGProperty::FlagType parentExMask) + wxPG_ITERATOR_CREATE_MASKS(flags, wxPGPropertyFlags itemExMask, wxPGPropertyFlags parentExMask) // First, get last child of last parent wxPGProperty* pwc = m_properties->Last(); @@ -609,7 +609,7 @@ void wxPropertyGridPageState::DoSortChildren(wxPGProperty* p, wxPGPropertyValues return; // Never sort children of aggregate properties - if ( p->HasFlag(wxPG_PROP_AGGREGATE) ) + if ( p->HasFlag(wxPGPropertyFlags::Aggregate) ) return; if ( !!(flags & wxPGPropertyValuesFlags::SortTopLevelOnly) @@ -1385,12 +1385,12 @@ wxVariant wxPropertyGridPageState::DoGetPropertyValues(const wxString& listname, { if ( !!(flags & wxPGPropertyValuesFlags::KeepStructure) ) { - wxASSERT( !pwc->HasFlag(wxPG_PROP_AGGREGATE) ); + wxASSERT( !pwc->HasFlag(wxPGPropertyFlags::Aggregate) ); for ( unsigned int i = 0; i < pwc->GetChildCount(); i++ ) { wxPGProperty* p = pwc->Item(i); - if ( !p->HasAnyChild() || p->HasFlag(wxPG_PROP_AGGREGATE) ) + if ( !p->HasAnyChild() || p->HasFlag(wxPGPropertyFlags::Aggregate) ) { wxVariant variant = p->GetValue(); variant.SetName( p->GetBaseName() ); @@ -1414,7 +1414,7 @@ wxVariant wxPropertyGridPageState::DoGetPropertyValues(const wxString& listname, const wxPGProperty* p = it.GetProperty(); // Use a trick to ignore wxParentProperty itself, but not its sub-properties. - if ( !p->HasAnyChild() || p->HasFlag(wxPG_PROP_AGGREGATE) ) + if ( !p->HasAnyChild() || p->HasFlag(wxPGPropertyFlags::Aggregate) ) { wxVariant variant = p->GetValue(); variant.SetName( p->GetName() ); @@ -1669,7 +1669,7 @@ wxPGProperty* wxPropertyGridPageState::DoInsert( wxPGProperty* parent, int index if ( !parent ) parent = m_properties; - wxCHECK_MSG( !parent->HasFlag(wxPG_PROP_AGGREGATE), + wxCHECK_MSG( !parent->HasFlag(wxPGPropertyFlags::Aggregate), wxNullProperty, wxS("when adding properties to fixed parents, use BeginAddChildren and EndAddChildren.") ); @@ -1739,7 +1739,7 @@ wxPGProperty* wxPropertyGridPageState::DoInsert( wxPGProperty* parent, int index // Update editor controls of all parents if they are containers of composed values. for( wxPGProperty *p = property->GetParent(); - p && !p->IsRoot() && !p->IsCategory() && p->HasFlag(wxPG_PROP_COMPOSED_VALUE); + p && !p->IsRoot() && !p->IsCategory() && p->HasFlag(wxPGPropertyFlags::ComposedValue); p = p->GetParent() ) { p->RefreshEditor(); @@ -1787,7 +1787,7 @@ void wxPropertyGridPageState::DoMarkChildrenAsDeleted(wxPGProperty* p, { wxPGProperty* child = p->Item(i); - child->SetFlag(wxPG_PROP_BEING_DELETED); + child->SetFlag(wxPGPropertyFlags::BeingDeleted); if ( recursive ) { @@ -1890,7 +1890,7 @@ void wxPropertyGridPageState::DoDelete( wxPGProperty* item, bool doDelete ) wxPGProperty* parent = item->GetParent(); - wxCHECK_RET( !parent->HasFlag(wxPG_PROP_AGGREGATE), + wxCHECK_RET( !parent->HasFlag(wxPGPropertyFlags::Aggregate), wxS("wxPropertyGrid: Do not attempt to remove sub-properties.") ); wxASSERT( item->GetParentState() == this ); @@ -1957,13 +1957,13 @@ void wxPropertyGridPageState::DoDelete( wxPGProperty* item, bool doDelete ) wxS("Current category cannot be deleted") ); // Prevent property and its children from being re-selected - item->SetFlag(wxPG_PROP_BEING_DELETED); + item->SetFlag(wxPGPropertyFlags::BeingDeleted); DoMarkChildrenAsDeleted(item, true); unsigned int indinparent = item->GetIndexInParent(); // Delete children - if ( item->HasAnyChild() && !item->HasFlag(wxPG_PROP_AGGREGATE) ) + if ( item->HasAnyChild() && !item->HasFlag(wxPGPropertyFlags::Aggregate) ) { // deleting a category item->DeleteChildren(); diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index 1ac680d1d6..259e4e9d6c 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -59,9 +59,9 @@ wxStringProperty::wxStringProperty( const wxString& label, void wxStringProperty::OnSetValue() { if ( !m_value.IsNull() && m_value.GetString() == wxS("") ) - SetFlag(wxPG_PROP_COMPOSED_VALUE); + SetFlag(wxPGPropertyFlags::ComposedValue); - if ( HasFlag(wxPG_PROP_COMPOSED_VALUE) ) + if ( HasFlag(wxPGPropertyFlags::ComposedValue) ) { wxString s; DoGenerateComposedValue(s); @@ -74,7 +74,7 @@ wxString wxStringProperty::ValueToString( wxVariant& value, { wxString s = value.GetString(); - if ( HasAnyChild() && HasFlag(wxPG_PROP_COMPOSED_VALUE) ) + if ( HasAnyChild() && HasFlag(wxPGPropertyFlags::ComposedValue) ) { // Value stored in m_value is non-editable, non-full value if ( (argFlags & wxPG_FULL_VALUE) || @@ -94,7 +94,7 @@ wxString wxStringProperty::ValueToString( wxVariant& value, // If string is password and value is for visual purposes, // then return asterisks instead the actual string. - if ( (m_flags & wxPG_PROP_PASSWORD) && !(argFlags & (wxPG_FULL_VALUE|wxPG_EDITABLE_VALUE)) ) + if ( !!(m_flags & wxPGPropertyFlags_Password) && !(argFlags & (wxPG_FULL_VALUE|wxPG_EDITABLE_VALUE)) ) return wxString(wxS('*'), s.length()); return s; @@ -102,7 +102,7 @@ wxString wxStringProperty::ValueToString( wxVariant& value, bool wxStringProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const { - if ( HasAnyChild() && HasFlag(wxPG_PROP_COMPOSED_VALUE) ) + if ( HasAnyChild() && HasFlag(wxPGPropertyFlags::ComposedValue) ) return wxPGProperty::StringToValue(variant, text, argFlags); if ( variant != text ) @@ -118,7 +118,7 @@ bool wxStringProperty::DoSetAttribute( const wxString& name, wxVariant& value ) { if ( name == wxPG_STRING_PASSWORD ) { - ChangeFlag(wxPG_PROP_PASSWORD, value.GetBool()); + ChangeFlag(wxPGPropertyFlags_Password, value.GetBool()); RecreateEditor(); return true; } @@ -1031,7 +1031,7 @@ const wxPGEditor* wxBoolProperty::DoGetEditorClass() const { // Select correct editor control. #if wxPG_INCLUDE_CHECKBOX - if ( !(m_flags & wxPG_PROP_USE_CHECKBOX) ) + if ( !(m_flags & wxPGPropertyFlags_UseCheckBox) ) return wxPGEditor_Choice; return wxPGEditor_CheckBox; #else @@ -1046,7 +1046,7 @@ wxBoolProperty::wxBoolProperty( const wxString& label, const wxString& name, boo SetValue(wxVariant(value)); - m_flags |= wxPG_PROP_USE_DCC; + m_flags |= wxPGPropertyFlags_UseDCC; } wxString wxBoolProperty::ValueToString( wxVariant& value, @@ -1124,13 +1124,13 @@ bool wxBoolProperty::DoSetAttribute( const wxString& name, wxVariant& value ) #if wxPG_INCLUDE_CHECKBOX if ( name == wxPG_BOOL_USE_CHECKBOX ) { - ChangeFlag(wxPG_PROP_USE_CHECKBOX, value.GetBool()); + ChangeFlag(wxPGPropertyFlags_UseCheckBox, value.GetBool()); return true; } #endif if ( name == wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING ) { - ChangeFlag(wxPG_PROP_USE_DCC, value.GetBool()); + ChangeFlag(wxPGPropertyFlags_UseDCC, value.GetBool()); return true; } return wxPGProperty::DoSetAttribute(name, value); @@ -1467,8 +1467,8 @@ void wxFlagsProperty::Init(long value) // Relay wxPG_BOOL_USE_CHECKBOX and wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING // to child bool property controls. - bool attrUseCheckBox = (m_flags & wxPG_PROP_USE_CHECKBOX) != 0; - bool attrUseDCC = (m_flags & wxPG_PROP_USE_DCC) != 0; + bool attrUseCheckBox = !!(m_flags & wxPGPropertyFlags_UseCheckBox); + bool attrUseDCC = !!(m_flags & wxPGPropertyFlags_UseDCC); for ( unsigned int i = 0; i < GetItemCount(); i++ ) { bool child_val = (value & m_choices.GetValue(i)) != 0; @@ -1495,7 +1495,7 @@ void wxFlagsProperty::Init(long value) wxFlagsProperty::wxFlagsProperty( const wxString& label, const wxString& name, const wxChar* const* labels, const long* values, long value ) : wxPGProperty(label,name) { - m_flags |= wxPG_PROP_USE_DCC; // same default like wxBoolProperty + m_flags |= wxPGPropertyFlags_UseDCC; // same default like wxBoolProperty if ( labels ) { @@ -1517,7 +1517,7 @@ wxFlagsProperty::wxFlagsProperty( const wxString& label, const wxString& name, const wxArrayString& labels, const wxArrayInt& values, int value ) : wxPGProperty(label,name) { - m_flags |= wxPG_PROP_USE_DCC; // same default like wxBoolProperty + m_flags |= wxPGPropertyFlags_UseDCC; // same default like wxBoolProperty if ( !labels.empty() ) { @@ -1539,7 +1539,7 @@ wxFlagsProperty::wxFlagsProperty( const wxString& label, const wxString& name, wxPGChoices& choices, long value ) : wxPGProperty(label,name) { - m_flags |= wxPG_PROP_USE_DCC; // same default like wxBoolProperty + m_flags |= wxPGPropertyFlags_UseDCC; // same default like wxBoolProperty if ( choices.IsOk() ) { @@ -1580,7 +1580,7 @@ void wxFlagsProperty::OnSetValue() long flag = m_choices.GetValue(i); if ( (newFlags & flag) != (m_oldValue & flag) ) - Item(i)->ChangeFlag( wxPG_PROP_MODIFIED, true ); + Item(i)->ChangeFlag(wxPGPropertyFlags::Modified, true ); } m_oldValue = newFlags; @@ -1681,7 +1681,7 @@ void wxFlagsProperty::RefreshChildren() wxPGProperty* p = Item(i); if ( subVal != (m_oldValue & flag) ) - p->ChangeFlag( wxPG_PROP_MODIFIED, true ); + p->ChangeFlag(wxPGPropertyFlags::Modified, true ); p->SetValue( subVal == flag?true:false ); } @@ -1707,7 +1707,7 @@ bool wxFlagsProperty::DoSetAttribute( const wxString& name, wxVariant& value ) { if ( name == wxPG_BOOL_USE_CHECKBOX ) { - ChangeFlag(wxPG_PROP_USE_CHECKBOX, value.GetBool()); + ChangeFlag(wxPGPropertyFlags_UseCheckBox, value.GetBool()); for ( wxPGProperty* child : m_children ) { @@ -1717,7 +1717,7 @@ bool wxFlagsProperty::DoSetAttribute( const wxString& name, wxVariant& value ) } else if ( name == wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING ) { - ChangeFlag(wxPG_PROP_USE_DCC, value.GetBool()); + ChangeFlag(wxPGPropertyFlags_UseDCC, value.GetBool()); for ( wxPGProperty* child : m_children ) { @@ -1737,7 +1737,7 @@ wxPG_IMPLEMENT_PROPERTY_CLASS(wxDirProperty, wxEditorDialogProperty, TextCtrlAnd wxDirProperty::wxDirProperty( const wxString& label, const wxString& name, const wxString& value ) : wxEditorDialogProperty(label, name) { - m_flags &= ~wxPG_PROP_ACTIVE_BTN; // Property button enabled only in not read-only mode. + m_flags &= ~wxPGPropertyFlags_ActiveButton; // Property button enabled only in not read-only mode. SetValue(value); } @@ -1867,8 +1867,8 @@ wxFileProperty::wxFileProperty( const wxString& label, const wxString& name, const wxString& value ) : wxEditorDialogProperty(label, name) { - m_flags |= wxPG_PROP_SHOW_FULL_FILENAME; - m_flags &= ~wxPG_PROP_ACTIVE_BTN; // Property button enabled only in not read-only mode. + m_flags |= wxPGPropertyFlags_ShowFullFileName; + m_flags &= ~wxPGPropertyFlags_ActiveButton; // Property button enabled only in not read-only mode. m_indFilter = -1; m_wildcard = wxALL_FILES; @@ -1974,7 +1974,7 @@ wxString wxFileProperty::ValueToString( wxVariant& value, { return filename.GetFullPath(); } - else if ( m_flags & wxPG_PROP_SHOW_FULL_FILENAME ) + else if ( !!(m_flags & wxPGPropertyFlags::ShowFullFileName) ) { if ( !m_basePath.empty() ) { @@ -1992,7 +1992,7 @@ bool wxFileProperty::StringToValue( wxVariant& variant, const wxString& text, in { wxFileName filename = variant.GetString(); - if ( (m_flags & wxPG_PROP_SHOW_FULL_FILENAME) || (argFlags & wxPG_FULL_VALUE) ) + if ( !!(m_flags & wxPGPropertyFlags::ShowFullFileName) || (argFlags & wxPG_FULL_VALUE) ) { if ( filename != text ) { @@ -2018,7 +2018,7 @@ bool wxFileProperty::DoSetAttribute( const wxString& name, wxVariant& value ) { if ( name == wxPG_FILE_SHOW_FULL_PATH ) { - ChangeFlag(wxPG_PROP_SHOW_FULL_FILENAME, value.GetBool()); + ChangeFlag(wxPGPropertyFlags_ShowFullFileName, value.GetBool()); return true; } else if ( name == wxPG_FILE_WILDCARD ) @@ -2031,7 +2031,7 @@ bool wxFileProperty::DoSetAttribute( const wxString& name, wxVariant& value ) m_basePath = value.GetString(); // Make sure wxPG_FILE_SHOW_FULL_PATH is also set - m_flags |= wxPG_PROP_SHOW_FULL_FILENAME; + m_flags |= wxPGPropertyFlags_ShowFullFileName; return true; } else if ( name == wxPG_FILE_INITIAL_PATH ) @@ -2095,7 +2095,7 @@ wxLongStringProperty::wxLongStringProperty( const wxString& label, const wxStrin const wxString& value ) : wxEditorDialogProperty(label, name) { - m_flags |= wxPG_PROP_ACTIVE_BTN; // Property button always enabled. + m_flags |= wxPGPropertyFlags_ActiveButton; // Property button always enabled. m_dlgStyle = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxCLIP_CHILDREN; SetValue(value); } @@ -2122,7 +2122,7 @@ bool wxLongStringProperty::DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& va wxBoxSizer* topsizer = new wxBoxSizer( wxVERTICAL ); wxBoxSizer* rowsizer = new wxBoxSizer( wxHORIZONTAL ); long edStyle = wxTE_MULTILINE; - if ( HasFlag(wxPG_PROP_READONLY) ) + if ( HasFlag(wxPGPropertyFlags::ReadOnly) ) edStyle |= wxTE_READONLY; wxString strVal; wxPropertyGrid::ExpandEscapeSequences(strVal, value.GetString()); @@ -2135,7 +2135,7 @@ bool wxLongStringProperty::DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& va topsizer->Add(rowsizer, wxSizerFlags(1).Expand()); long btnSizerFlags = wxCANCEL; - if ( !HasFlag(wxPG_PROP_READONLY) ) + if ( !HasFlag(wxPGPropertyFlags::ReadOnly) ) btnSizerFlags |= wxOK; wxStdDialogButtonSizer* buttonSizer = dlg->CreateStdDialogButtonSizer(btnSizerFlags); topsizer->Add(buttonSizer, wxSizerFlags(0).Right().Border(wxBOTTOM|wxRIGHT, spacing)); diff --git a/tests/controls/propgridtest.cpp b/tests/controls/propgridtest.cpp index f1c7e5727f..2314fbd5a5 100644 --- a/tests/controls/propgridtest.cpp +++ b/tests/controls/propgridtest.cpp @@ -507,7 +507,7 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") wxPGProperty* p = it.GetProperty(); if ( p->IsCategory() ) FAIL_CHECK(wxString::Format("'%s' is a category (non-private child property expected)", p->GetLabel()).c_str()); - else if ( p->GetParent()->HasFlag(wxPG_PROP_AGGREGATE) ) + else if ( p->GetParent()->HasFlag(wxPGPropertyFlags::Aggregate) ) FAIL_CHECK(wxString::Format("'%s' is a private child (non-private child property expected)", p->GetLabel()).c_str()); count++; } @@ -527,7 +527,7 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") for ( auto it = pgManager->GetVIterator(wxPG_ITERATE_PROPERTIES | wxPG_ITERATE_CATEGORIES); !it.AtEnd(); it.Next() ) { wxPGProperty* p = it.GetProperty(); - if ( p->GetParent()->HasFlag(wxPG_PROP_AGGREGATE) ) + if ( p->GetParent()->HasFlag(wxPGPropertyFlags::Aggregate) ) FAIL_CHECK(wxString::Format("'%s' is a private child (non-private child property or category expected)", p->GetLabel()).c_str()); count++; } @@ -539,7 +539,7 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") wxPGProperty* p = it.GetProperty(); if ( (p->GetParent() != p->GetGrid()->GetRoot() && !p->GetParent()->IsExpanded()) ) FAIL_CHECK(wxString::Format("'%s' had collapsed parent (only visible properties expected)", p->GetLabel()).c_str()); - else if ( p->HasFlag(wxPG_PROP_HIDDEN) ) + else if ( p->HasFlag(wxPGPropertyFlags::Hidden) ) FAIL_CHECK(wxString::Format("'%s' was hidden (only visible properties expected)", p->GetLabel()).c_str()); count++; } @@ -697,7 +697,7 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") // Delete everything in reverse order std::vector array; - for ( auto it = pgManager->GetVIterator(wxPG_ITERATE_ALL & ~(wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE))); !it.AtEnd(); it.Next() ) + for ( auto it = pgManager->GetVIterator(wxPG_ITERATE_ALL & ~(wxPG_IT_CHILDREN(wxPGPropertyFlags::Aggregate))); !it.AtEnd(); it.Next() ) { array.push_back(it.GetProperty()); } @@ -710,7 +710,7 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") } // Check if grid is empty. - auto it = pgManager->GetVIterator(wxPG_ITERATE_ALL & ~(wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE))); + auto it = pgManager->GetVIterator(wxPG_ITERATE_ALL & ~(wxPG_IT_CHILDREN(wxPGPropertyFlags::Aggregate))); if ( !it.AtEnd() ) { FAIL_CHECK("Not all properties are deleted"); @@ -1597,22 +1597,22 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") wxPGProperty* p = *it; // Save initial flags - wxPGProperty::FlagType oldFlags = 0; - if ( p->HasFlag(wxPG_PROP_COLLAPSED) ) + wxPGPropertyFlags oldFlags = wxPGPropertyFlags::Null; + if ( p->HasFlag(wxPGPropertyFlags::Collapsed) ) { - oldFlags |= wxPG_PROP_COLLAPSED; + oldFlags |= wxPGPropertyFlags::Collapsed; } - if ( p->HasFlag(wxPG_PROP_DISABLED) ) + if ( p->HasFlag(wxPGPropertyFlags::Disabled) ) { - oldFlags |= wxPG_PROP_DISABLED; + oldFlags |= wxPGPropertyFlags::Disabled; } - if ( p->HasFlag(wxPG_PROP_HIDDEN) ) + if ( p->HasFlag(wxPGPropertyFlags::Hidden) ) { - oldFlags |= wxPG_PROP_HIDDEN; + oldFlags |= wxPGPropertyFlags::Hidden; } - if ( p->HasFlag(wxPG_PROP_NOEDITOR) ) + if ( p->HasFlag(wxPGPropertyFlags::NoEditor) ) { - oldFlags |= wxPG_PROP_NOEDITOR; + oldFlags |= wxPGPropertyFlags::NoEditor; } wxString flags; @@ -1652,37 +1652,37 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") // Verify if flags have been properly set if ( flags.Find("COLLAPSED") != wxNOT_FOUND && - !p->HasFlag(wxPG_PROP_COLLAPSED) ) + !p->HasFlag(wxPGPropertyFlags::Collapsed) ) { FAIL_CHECK(wxString::Format("Error setting flag from string 'COLLAPSED' for property '%s'", p->GetName()).c_str()); } if ( flags.Find("COLLAPSED") == wxNOT_FOUND && - p->HasFlag(wxPG_PROP_COLLAPSED) ) + p->HasFlag(wxPGPropertyFlags::Collapsed) ) { FAIL_CHECK(wxString::Format("Error resetting flag from string 'COLLAPSED'for property '%s'", p->GetName()).c_str()); } if ( flags.Find("DISABLED") != wxNOT_FOUND && - !p->HasFlag(wxPG_PROP_DISABLED) ) + !p->HasFlag(wxPGPropertyFlags::Disabled) ) { FAIL_CHECK(wxString::Format("Error setting flag from string 'DISABLED' for property '%s'", p->GetName()).c_str()); } if ( flags.Find("DISABLED") == wxNOT_FOUND && - p->HasFlag(wxPG_PROP_DISABLED) ) + p->HasFlag(wxPGPropertyFlags::Disabled) ) { FAIL_CHECK(wxString::Format("Error resetting flag from string 'DISABLED' for property '%s'", p->GetName()).c_str()); } if ( flags.Find("HIDDEN") != wxNOT_FOUND && - !p->HasFlag(wxPG_PROP_HIDDEN) ) + !p->HasFlag(wxPGPropertyFlags::Hidden) ) { FAIL_CHECK(wxString::Format("Error setting flag from string 'HIDDEN' for property '%s'", p->GetName()).c_str()); } if ( flags.Find("HIDDEN") == wxNOT_FOUND && - p->HasFlag(wxPG_PROP_HIDDEN) ) + p->HasFlag(wxPGPropertyFlags::Hidden) ) { FAIL_CHECK(wxString::Format("Error resetting flag from string 'HIDDEN' for property '%s'", p->GetName()).c_str()); @@ -1691,8 +1691,8 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") // Get individual flags bool ok; - flags = p->GetFlagsAsString(wxPG_PROP_COLLAPSED); - if ( p->HasFlag(wxPG_PROP_COLLAPSED) ) + flags = p->GetFlagsAsString(wxPGPropertyFlags::Collapsed); + if ( p->HasFlag(wxPGPropertyFlags::Collapsed) ) { ok = (flags == "COLLAPSED"); } @@ -1702,12 +1702,12 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") } if ( !ok ) { - FAIL_CHECK(wxString::Format("Invalid string for wxPG_PROP_COLLAPSED flag for property '%s'", + FAIL_CHECK(wxString::Format("Invalid string for wxPGPropertyFlags::Collapsed flag for property '%s'", p->GetName()).c_str()); } - flags = p->GetFlagsAsString(wxPG_PROP_DISABLED); - if ( p->HasFlag(wxPG_PROP_DISABLED) ) + flags = p->GetFlagsAsString(wxPGPropertyFlags::Disabled); + if ( p->HasFlag(wxPGPropertyFlags::Disabled) ) { ok = (flags == "DISABLED"); } @@ -1717,12 +1717,12 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") } if ( !ok ) { - FAIL_CHECK(wxString::Format("Invalid string for wxPG_PROP_DISABLED flag for property '%s'", + FAIL_CHECK(wxString::Format("Invalid string for wxPGPropertyFlags::Disabled flag for property '%s'", p->GetName()).c_str()); } - flags = p->GetFlagsAsString(wxPG_PROP_HIDDEN); - if ( p->HasFlag(wxPG_PROP_HIDDEN) ) + flags = p->GetFlagsAsString(wxPGPropertyFlags::Hidden); + if ( p->HasFlag(wxPGPropertyFlags::Hidden) ) { ok = (flags == "HIDDEN"); } @@ -1732,12 +1732,12 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") } if ( !ok ) { - FAIL_CHECK(wxString::Format("Invalid string for wxPG_PROP_HIDDEN flag for property '%s'", + FAIL_CHECK(wxString::Format("Invalid string for wxPGPropertyFlags::Hidden flag for property '%s'", p->GetName()).c_str()); } - flags = p->GetFlagsAsString(wxPG_PROP_NOEDITOR); - if ( p->HasFlag(wxPG_PROP_NOEDITOR) ) + flags = p->GetFlagsAsString(wxPGPropertyFlags::NoEditor); + if ( p->HasFlag(wxPGPropertyFlags::NoEditor) ) { ok = (flags == "NOEDITOR"); } @@ -1747,13 +1747,13 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") } if ( !ok ) { - FAIL_CHECK(wxString::Format("Invalid string for wxPG_PROP_NOEDITOR flag for property '%s'", + FAIL_CHECK(wxString::Format("Invalid string for wxPGPropertyFlags::NoEditor flag for property '%s'", p->GetName()).c_str()); } // Get all flags - flags = p->GetFlagsAsString(wxPG_STRING_STORED_FLAGS); - if ( p->HasFlag(wxPG_PROP_COLLAPSED) ) + flags = p->GetFlagsAsString(wxPGPropertyFlags::StringStoredFlags); + if ( p->HasFlag(wxPGPropertyFlags::Collapsed) ) { ok = (flags.Find("COLLAPSED") != wxNOT_FOUND); } @@ -1763,11 +1763,11 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") } if ( !ok ) { - FAIL_CHECK(wxString::Format("Invalid string for wxPG_PROP_COLLAPSED flag for property '%s'", + FAIL_CHECK(wxString::Format("Invalid string for wxPGPropertyFlags::Collapsed flag for property '%s'", p->GetName()).c_str()); } - if ( p->HasFlag(wxPG_PROP_DISABLED) ) + if ( p->HasFlag(wxPGPropertyFlags::Disabled) ) { ok = (flags.Find("DISABLED") != wxNOT_FOUND); } @@ -1777,11 +1777,11 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") } if ( !ok ) { - FAIL_CHECK(wxString::Format("Invalid string for wxPG_PROP_DISBALED flag for property '%s'", + FAIL_CHECK(wxString::Format("Invalid string for wxPGPropertyFlags::Disabled flag for property '%s'", p->GetName()).c_str()); } - if ( p->HasFlag(wxPG_PROP_HIDDEN) ) + if ( p->HasFlag(wxPGPropertyFlags::Hidden) ) { ok = (flags.Find("HIDDEN") != wxNOT_FOUND); } @@ -1791,11 +1791,11 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") } if ( !ok ) { - FAIL_CHECK(wxString::Format("Invalid string for wxPG_PROP_HIDDEN flag for property '%s'", + FAIL_CHECK(wxString::Format("Invalid string for wxPGPropertyFlags::Hidden flag for property '%s'", p->GetName()).c_str()); } - if ( p->HasFlag(wxPG_PROP_NOEDITOR) ) + if ( p->HasFlag(wxPGPropertyFlags::NoEditor) ) { ok = (flags.Find("NOEDITOR") != wxNOT_FOUND); } @@ -1805,15 +1805,15 @@ TEST_CASE("PropertyGridTestCase", "[propgrid]") } if ( !ok ) { - FAIL_CHECK(wxString::Format("Invalid string for wxPG_PROP_NOEDITOR flag for property '%s'", + FAIL_CHECK(wxString::Format("Invalid string for wxPGPropertyFlags::NoEditor flag for property '%s'", p->GetName()).c_str()); } // Restore original flags - p->ChangeFlag(wxPG_PROP_COLLAPSED, (oldFlags & wxPG_PROP_COLLAPSED) != 0); - p->ChangeFlag(wxPG_PROP_DISABLED, (oldFlags & wxPG_PROP_DISABLED) != 0); - p->ChangeFlag(wxPG_PROP_HIDDEN, (oldFlags & wxPG_PROP_HIDDEN) != 0); - p->ChangeFlag(wxPG_PROP_NOEDITOR, (oldFlags & wxPG_PROP_NOEDITOR) != 0); + p->ChangeFlag(wxPGPropertyFlags::Collapsed, !!(oldFlags & wxPGPropertyFlags::Collapsed)); + p->ChangeFlag(wxPGPropertyFlags::Disabled, !!(oldFlags & wxPGPropertyFlags::Disabled)); + p->ChangeFlag(wxPGPropertyFlags::Hidden, !!(oldFlags & wxPGPropertyFlags::Hidden)); + p->ChangeFlag(wxPGPropertyFlags::NoEditor, !!(oldFlags & wxPGPropertyFlags::NoEditor)); } } } From 6a5b0667b534685e49b9a3244e52a3a05490065f Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 23 Dec 2023 21:07:01 +0100 Subject: [PATCH 097/257] Remove macro from wxPGPropertyGridIterator-related code Remove simple wxPG_ITERATOR_PARENTEXMASK_TEST macro and use just the code to increase code readability. --- include/wx/propgrid/propgridpagestate.h | 9 --------- src/propgrid/propgridpagestate.cpp | 14 ++++++-------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/include/wx/propgrid/propgridpagestate.h b/include/wx/propgrid/propgridpagestate.h index e6c87c625c..da63e0d754 100644 --- a/include/wx/propgrid/propgridpagestate.h +++ b/include/wx/propgrid/propgridpagestate.h @@ -283,15 +283,6 @@ wxPG_ITERATE_DEFAULT = wxPG_ITERATE_NORMAL B = static_cast(((FLAGS>>16) ^ wxPG_ITERATOR_MASK_OP_PARENT) & \ wxPG_ITERATOR_MASK_OP_PARENT & 0xFFFF); - -// Macro to test if children of PWC should be iterated through -#define wxPG_ITERATOR_PARENTEXMASK_TEST(PWC, PARENTMASK) \ - ( \ - !PWC->HasFlag(PARENTMASK) && \ - PWC->HasAnyChild() \ - ) - - // Base for wxPropertyGridIterator classes. class WXDLLIMPEXP_PROPGRID wxPropertyGridIteratorBase { diff --git a/src/propgrid/propgridpagestate.cpp b/src/propgrid/propgridpagestate.cpp index 0b6e430ab7..27b93ffdca 100644 --- a/src/propgrid/propgridpagestate.cpp +++ b/src/propgrid/propgridpagestate.cpp @@ -108,9 +108,8 @@ void wxPropertyGridIteratorBase::Prev() property = parent->Item(index); - // Go to last children? - if ( property->HasAnyChild() && - wxPG_ITERATOR_PARENTEXMASK_TEST(property, m_parentExMask) ) + // Go to last child if children of property should be iterated through) + if ( property->HasAnyChild() && !property->HasFlag(m_parentExMask) ) { // First child property = property->Last(); @@ -143,8 +142,8 @@ void wxPropertyGridIteratorBase::Next( bool iterateChildren ) if ( !property ) return; - if ( property->HasAnyChild() && - wxPG_ITERATOR_PARENTEXMASK_TEST(property, m_parentExMask) && + // Go to first child if children of property should be iterated through + if ( property->HasAnyChild() && !property->HasFlag(m_parentExMask) && iterateChildren ) { // First child @@ -404,10 +403,9 @@ wxPGProperty* wxPropertyGridPageState::GetLastItem( int flags ) wxPG_ITERATOR_CREATE_MASKS(flags, wxPGPropertyFlags itemExMask, wxPGPropertyFlags parentExMask) - // First, get last child of last parent + // First, get last child of last parent if children of 'pwc' should be iterated through wxPGProperty* pwc = m_properties->Last(); - while ( pwc->HasAnyChild() && - wxPG_ITERATOR_PARENTEXMASK_TEST(pwc, parentExMask) ) + while ( pwc->HasAnyChild() && !pwc->HasFlag(parentExMask) ) pwc = pwc->Last(); // Then, if it doesn't fit our criteria, back up until we find something that does From 5725f0be4151f7ac3086e0535750c1114dbb8daa Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 23 Dec 2023 22:23:10 +0100 Subject: [PATCH 098/257] Replace macro with inline function in wxPGPropertyGridIterator-related code Replace wxPG_ITERATOR_CREATE_MASKS macro with inline function to ensure type safety. --- include/wx/propgrid/propgridpagestate.h | 19 ++++++++++++++----- src/propgrid/propgridpagestate.cpp | 6 ++++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/include/wx/propgrid/propgridpagestate.h b/include/wx/propgrid/propgridpagestate.h index da63e0d754..7c0576543c 100644 --- a/include/wx/propgrid/propgridpagestate.h +++ b/include/wx/propgrid/propgridpagestate.h @@ -276,12 +276,21 @@ wxPG_ITERATE_DEFAULT = wxPG_ITERATE_NORMAL }; - -#define wxPG_ITERATOR_CREATE_MASKS(FLAGS, A, B) \ - A = static_cast((FLAGS ^ wxPG_ITERATOR_MASK_OP_ITEM) & \ - wxPG_ITERATOR_MASK_OP_ITEM & 0xFFFF); \ - B = static_cast(((FLAGS>>16) ^ wxPG_ITERATOR_MASK_OP_PARENT) & \ +inline void wxPGCreateIteratorMasks(int flags, wxPGPropertyFlags& itemExMask, wxPGPropertyFlags& parentExMask) +{ + itemExMask = static_cast((flags ^ wxPG_ITERATOR_MASK_OP_ITEM) & + wxPG_ITERATOR_MASK_OP_ITEM & 0xFFFF); + parentExMask = static_cast(((flags >> 16) ^ wxPG_ITERATOR_MASK_OP_PARENT) & wxPG_ITERATOR_MASK_OP_PARENT & 0xFFFF); +} + +#if WXWIN_COMPATIBILITY_3_2 +#ifdef wxPG_MUST_DEPRECATE_MACRO_NAME +#pragma deprecated(wxPG_ITERATOR_CREATE_MASKS) +#endif +#define wxPG_ITERATOR_CREATE_MASKS wxPG_DEPRECATED_MACRO_VALUE(wxPGCreateIteratorMasks,\ + "wxPG_ITERATOR_CREATE_MASKS is deprecated. Call wxPGCreateIteratorMasks instead.") +#endif // WXWIN_COMPATIBILITY_3_2 // Base for wxPropertyGridIterator classes. class WXDLLIMPEXP_PROPGRID wxPropertyGridIteratorBase diff --git a/src/propgrid/propgridpagestate.cpp b/src/propgrid/propgridpagestate.cpp index 27b93ffdca..c45c1b1e65 100644 --- a/src/propgrid/propgridpagestate.cpp +++ b/src/propgrid/propgridpagestate.cpp @@ -47,7 +47,7 @@ void wxPropertyGridIteratorBase::Init( wxPropertyGridPageState* state, int flags m_property = property; - wxPG_ITERATOR_CREATE_MASKS(flags, m_itemExMask, m_parentExMask) + wxPGCreateIteratorMasks(flags, m_itemExMask, m_parentExMask); // Need to skip first? if ( property && property->HasFlag(m_itemExMask) ) @@ -401,7 +401,9 @@ wxPGProperty* wxPropertyGridPageState::GetLastItem( int flags ) if ( !m_properties->HasAnyChild() ) return nullptr; - wxPG_ITERATOR_CREATE_MASKS(flags, wxPGPropertyFlags itemExMask, wxPGPropertyFlags parentExMask) + wxPGPropertyFlags itemExMask; + wxPGPropertyFlags parentExMask; + wxPGCreateIteratorMasks(flags, itemExMask, parentExMask); // First, get last child of last parent if children of 'pwc' should be iterated through wxPGProperty* pwc = m_properties->Last(); From ab0a44a63a23d148fb2e468164686581be90734a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 18:59:01 +0100 Subject: [PATCH 099/257] Give information about which section of grid tests fails This is useful to see when the failure occurs exactly as the same checks are performed in 3 different cases. --- tests/controls/gridtest.cpp | 63 +++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 17 deletions(-) diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 638a82bbe5..60a957ca5c 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -537,9 +537,13 @@ TEST_CASE_METHOD(GridTestCase, "Grid::LabelClick", "[grid]") if ( !EnableUITests() ) return; - SECTION("Default") {} - SECTION("Native header") { m_grid->UseNativeColHeader(); } - SECTION("Native labels") { m_grid->SetUseNativeColLabels(); } + wxString desc; + + SECTION("Default") { desc = "default header"; } + SECTION("Native header") { desc = "native header"; m_grid->UseNativeColHeader(); } + SECTION("Native labels") { desc = "native labels"; m_grid->SetUseNativeColLabels(); } + + INFO("Using " << desc); EventCounter lclick(m_grid, wxEVT_GRID_LABEL_LEFT_CLICK); EventCounter ldclick(m_grid, wxEVT_GRID_LABEL_LEFT_DCLICK); @@ -599,9 +603,13 @@ TEST_CASE_METHOD(GridTestCase, "Grid::SortClick", "[grid]") if ( !EnableUITests() ) return; - SECTION("Default") {} - SECTION("Native header") { m_grid->UseNativeColHeader(); } - SECTION("Native labels") { m_grid->SetUseNativeColLabels(); } + wxString desc; + + SECTION("Default") { desc = "default header"; } + SECTION("Native header") { desc = "native header"; m_grid->UseNativeColHeader(); } + SECTION("Native labels") { desc = "native labels"; m_grid->SetUseNativeColLabels(); } + + INFO("Using " << desc); m_grid->SetSortingColumn(0); @@ -1057,8 +1065,12 @@ TEST_CASE_METHOD(GridTestCase, "Grid::AddRowCol", "[grid]") TEST_CASE_METHOD(GridTestCase, "Grid::DeleteAndAddRowCol", "[grid]") { - SECTION("Default") {} - SECTION("Native header") { m_grid->UseNativeColHeader(); } + wxString desc; + + SECTION("Default") { desc = "default header"; } + SECTION("Native header") { desc = "native header"; m_grid->UseNativeColHeader(); } + + INFO("Using " << desc); CHECK(m_grid->GetNumberRows() == 10); CHECK(m_grid->GetNumberCols() == 2); @@ -1089,9 +1101,13 @@ TEST_CASE_METHOD(GridTestCase, "Grid::DeleteAndAddRowCol", "[grid]") TEST_CASE_METHOD(GridTestCase, "Grid::ColumnOrder", "[grid]") { - SECTION("Default") {} - SECTION("Native header") { m_grid->UseNativeColHeader(); } - SECTION("Native labels") { m_grid->SetUseNativeColLabels(); } + wxString desc; + + SECTION("Default") { desc = "default header"; } + SECTION("Native header") { desc = "native header"; m_grid->UseNativeColHeader(); } + SECTION("Native labels") { desc = "native labels"; m_grid->SetUseNativeColLabels(); } + + INFO("Using " << desc); m_grid->AppendCols(2); @@ -1504,8 +1520,12 @@ TEST_CASE_METHOD(GridTestCase, "Grid::ResizeScrolledHeader", "[grid]") wxSKIP_AUTOMATIC_TEST_IF_GTK2(); - SECTION("Default") {} - SECTION("Native header") { m_grid->UseNativeColHeader(); } + wxString desc; + + SECTION("Default") { desc = "default header"; } + SECTION("Native header") { desc = "native header"; m_grid->UseNativeColHeader(); } + + INFO("Using " << desc); int const startwidth = m_grid->GetColSize(0); int const draglength = 100; @@ -1555,7 +1575,9 @@ TEST_CASE_METHOD(GridTestCase, "Grid::ColumnMinWidth", "[grid]") wxSKIP_AUTOMATIC_TEST_IF_GTK2(); - SECTION("Default") {} + wxString desc; + + SECTION("Default") { desc = "default header"; } SECTION("Native header") { // For some unknown reason, this test fails under AppVeyor even though @@ -1564,9 +1586,12 @@ TEST_CASE_METHOD(GridTestCase, "Grid::ColumnMinWidth", "[grid]") if ( IsAutomaticTest() ) return; + desc = "native header"; m_grid->UseNativeColHeader(); } + INFO("Using " << desc); + int const startminwidth = m_grid->GetColMinimalAcceptableWidth(); m_grid->SetColMinimalAcceptableWidth(startminwidth*2); int const newminwidth = m_grid->GetColMinimalAcceptableWidth(); @@ -1612,9 +1637,13 @@ void GridTestCase::CheckFirstColAutoSize(int expected) TEST_CASE_METHOD(GridTestCase, "Grid::AutoSizeColumn", "[grid]") { - SECTION("Default") {} - SECTION("Native header") { m_grid->UseNativeColHeader(); } - SECTION("Native labels") { m_grid->SetUseNativeColLabels(); } + wxString desc; + + SECTION("Default") { desc = "default header"; } + SECTION("Native header") { desc = "native header"; m_grid->UseNativeColHeader(); } + SECTION("Native labels") { desc = "native labels"; m_grid->SetUseNativeColLabels(); } + + INFO("Using " << desc); // Hardcoded extra margin for the columns used in grid.cpp. const int margin = m_grid->FromDIP(10); From 8218e314184e0da4c5d0aaffdd3b5eabe09b974b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Dec 2023 19:42:08 +0100 Subject: [PATCH 100/257] Abandon tests waiting for mouse events if mouse moved If the mouse pointer moves, for whatever unexplained reason, the click is not going to happen, so don't wait for it. --- tests/controls/gridtest.cpp | 64 +++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 13 deletions(-) diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 60a957ca5c..80907c9f03 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -194,6 +194,41 @@ void FitGridToMulticell(TestableGrid* grid, const Multicell& multi) } } +// Function used to wait until the given predicate becomes true or timeout +// expires or the mouse moves away, in which case the test is abandoned. +bool +WaitForEventAt( + const wxPoint& pos, + const char* what, + const std::function& pred, + int timeout = 500 +) +{ + wxStopWatch sw; + for ( ;; ) + { + wxYield(); + + if ( pred() ) + break; + + if ( wxGetMousePosition() != pos ) + { + WARN("Mouse unexpectedly moved to " << wxGetMousePosition() + << " from the expected " << pos << "; skipping test"); + return false; + } + + if ( sw.Time() > timeout ) + { + FAIL("Timed out waiting for " << what); + break; // unreachable + } + } + + return true; +} + } // anonymous namespace namespace Catch @@ -559,29 +594,32 @@ TEST_CASE_METHOD(GridTestCase, "Grid::LabelClick", "[grid]") wxYield(); sim.MouseClick(); - WaitFor("mouse click to be processed", [&]() { - return lclick.GetCount() != 0; - }); + if ( !WaitForEventAt(pos, "mouse click to be processed", [&]() { + return lclick.GetCount() != 0; + }) ) + return; CHECK(lclick.GetCount() == 1); sim.MouseDblClick(); - WaitFor("mouse double click to be processed", [&]() { - return ldclick.GetCount() != 0; - }); + if ( !WaitForEventAt(pos, "mouse double click to be processed", [&]() { + return ldclick.GetCount() != 0; + }) ) + return; CHECK(ldclick.GetCount() == 1); sim.MouseClick(wxMOUSE_BTN_RIGHT); - WaitFor("mouse right click to be processed", [&]() { - return rclick.GetCount() != 0; - }); - + if ( !WaitForEventAt(pos, "mouse right click to be processed", [&]() { + return rclick.GetCount() != 0; + }) ) + return; CHECK(rclick.GetCount() == 1); rclick.Clear(); sim.MouseDblClick(wxMOUSE_BTN_RIGHT); - WaitFor("mouse right double click to be processed", [&]() { - return rclick.GetCount() != 0; - }); + if ( !WaitForEventAt(pos, "mouse right double click to be processed", [&]() { + return rclick.GetCount() != 0; + }) ) + return; if ( m_grid->IsUsingNativeHeader() ) { From 216b5a4b232f6d8117e08e0b76a9b520a7ee717d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 15:16:40 +0100 Subject: [PATCH 101/257] Also use WaitForEventAt() in Grid::SortClick test case Abandon this test too if the mouse moves for whatever reason. --- tests/controls/gridtest.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 80907c9f03..4beb91becb 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -662,10 +662,10 @@ TEST_CASE_METHOD(GridTestCase, "Grid::SortClick", "[grid]") wxYield(); sim.MouseClick(); - WaitFor("mouse click to be processed", [&]() { - return sort.GetCount() != 0; - }); - + if ( !WaitForEventAt(pos, "mouse click to be processed", [&]() { + return sort.GetCount() != 0; + }) ) + return; CHECK(sort.GetCount() == 1); #endif } From 61edcbc5a67574d60eacddce512cba6f8f9ac7bb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 17:06:44 +0100 Subject: [PATCH 102/257] Use WaitForEventAt() in Grid::CellClick test too This test doesn't use the native header but somehow still fails on AppVeyor and locally a very failure can be reproduced if the mouse is moved while the test runs, so check for this here too. --- tests/controls/gridtest.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 4beb91becb..3f40f15bd6 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -474,13 +474,18 @@ TEST_CASE_METHOD(GridTestCase, "Grid::CellClick", "[grid]") wxYield(); sim.MouseClick(); - wxYield(); - + if ( !WaitForEventAt(point, "mouse click to be processed", [&]() { + return lclick.GetCount() != 0; + }) ) + return; CHECK(lclick.GetCount() == 1); lclick.Clear(); sim.MouseDblClick(); - wxYield(); + if ( !WaitForEventAt(point, "double click to be processed", [&]() { + return lclick.GetCount() != 0 || ldclick.GetCount() != 0; + }) ) + return; //A double click event sends a single click event first //test to ensure this still happens in the future @@ -488,13 +493,18 @@ TEST_CASE_METHOD(GridTestCase, "Grid::CellClick", "[grid]") CHECK(ldclick.GetCount() == 1); sim.MouseClick(wxMOUSE_BTN_RIGHT); - wxYield(); - + if ( !WaitForEventAt(point, "right click to be processed", [&]() { + return rclick.GetCount() != 0; + }) ) + return; CHECK(rclick.GetCount() == 1); rclick.Clear(); sim.MouseDblClick(wxMOUSE_BTN_RIGHT); - wxYield(); + if ( !WaitForEventAt(point, "right double click to be processed", [&]() { + return rclick.GetCount() != 0 || rdclick.GetCount() != 0; + }) ) + return; CHECK(rclick.GetCount() == 1); CHECK(rdclick.GetCount() == 1); From 24952d0203b4d13ec57abe124fa06832bd45b2b1 Mon Sep 17 00:00:00 2001 From: PB Date: Sat, 23 Dec 2023 18:49:41 +0100 Subject: [PATCH 103/257] Fix confusing argument names in wxPersistentWindow docs Use the same argument name as in the actual code in the class constructor as well as the convenience function, instead of wrongly copypasted "book". See also 33de6dc (Fix confusing wxPersistentTLW ctor argument name, 2023-12-22). Closes #24158. --- interface/wx/persist/dataview.h | 2 +- interface/wx/persist/toplevel.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/wx/persist/dataview.h b/interface/wx/persist/dataview.h index b98896879b..865b1f64c3 100644 --- a/interface/wx/persist/dataview.h +++ b/interface/wx/persist/dataview.h @@ -39,4 +39,4 @@ public: }; /// Overload allowing persistence adapter creation for wxDataViewCtrl objects. -wxPersistentObject *wxCreatePersistentObject(wxDataViewCtrl *book); +wxPersistentObject *wxCreatePersistentObject(wxDataViewCtrl *control); diff --git a/interface/wx/persist/toplevel.h b/interface/wx/persist/toplevel.h index c8c4a7c822..2581e5f115 100644 --- a/interface/wx/persist/toplevel.h +++ b/interface/wx/persist/toplevel.h @@ -21,10 +21,10 @@ public: /** Constructor. - @param topwin + @param tlw The associated window. */ - wxPersistentTLW(wxTopLevelWindow *topwin); + wxPersistentTLW(wxTopLevelWindow *tlw); /** Save the current window geometry. @@ -39,4 +39,4 @@ public: /// Overload allowing persistence adapter creation for wxTopLevelWindow-derived /// objects. -wxPersistentObject *wxCreatePersistentObject(wxTopLevelWindow *book); +wxPersistentObject *wxCreatePersistentObject(wxTopLevelWindow *tlw); From a884d7da2f94910546471526befeed0b489c60dc Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 17:18:17 +0100 Subject: [PATCH 104/257] Re-realize wxAuiToolBar from SetOrientation() This doesn't really change anything because the only existing caller of SetOrientation() already called Realize() immediately afterwards anyhow but it seems more logical to do it from SetOrientation() itself, as it always needs to be done when the orientation changes. --- src/aui/auibar.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index 0a70bbcc1a..6ef60030f0 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -1412,6 +1412,8 @@ void wxAuiToolBar::SetOrientation(int orientation) { m_orientation = wxOrientation(orientation); SetArtFlags(); + + Realize(); } } @@ -2374,7 +2376,7 @@ void wxAuiToolBar::OnIdle(wxIdleEvent& evt) if (newOrientation != m_orientation) { SetOrientation(newOrientation); - Realize(); + if (newOrientation == wxHORIZONTAL) { pane.best_size = GetHintSize(wxAUI_DOCK_TOP); From 2573e61c19964da47a674170f706997c3426a364 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 17:24:55 +0100 Subject: [PATCH 105/257] Fix harmless MSVC warning about uninitialized variables in a test MSVS 2022 gave C4701 when std::isinf(d) was used below in release build. --- tests/strings/strings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/strings/strings.cpp b/tests/strings/strings.cpp index 3d8798699f..65ba92da1b 100644 --- a/tests/strings/strings.cpp +++ b/tests/strings/strings.cpp @@ -784,7 +784,7 @@ TEST_CASE("StringToULongLong", "[wxString]") TEST_CASE("StringToDouble", "[wxString]") { - double d; + double d = 0.0; static const struct ToDoubleData { const wxChar *str; From bbba3b7cb9b37cc33713c18233ff299ca71c8bc7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 17:39:35 +0100 Subject: [PATCH 106/257] Make wxAuiToolBar::RealizeHelper() return value actually useful This function used to return bool, but it didn't just always return true, but it's not even clear how could it possibly fail in theory, so this was quite useless. But Realize() itself used GetSize() after each call to RealizeHelper(), so just make RealizeHelper() itself return this size, which allows to shorten the code and get rid of a couple of levels of indentation. No real changes. --- include/wx/aui/auibar.h | 3 ++- src/aui/auibar.cpp | 29 +++++++---------------------- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/include/wx/aui/auibar.h b/include/wx/aui/auibar.h index 937f6e5107..b85c85fdf0 100644 --- a/include/wx/aui/auibar.h +++ b/include/wx/aui/auibar.h @@ -693,7 +693,6 @@ protected: bool m_gripperVisible; bool m_overflowVisible; - bool RealizeHelper(wxClientDC& dc, bool horizontal); static bool IsPaneValid(long style, const wxAuiPaneInfo& pane); bool IsPaneValid(long style) const; void SetArtFlags() const; @@ -705,6 +704,8 @@ private: // Common part of OnLeaveWindow() and OnCaptureLost(). void DoResetMouseState(); + wxSize RealizeHelper(wxClientDC& dc, bool horizontal); + wxDECLARE_EVENT_TABLE(); wxDECLARE_CLASS(wxAuiToolBar); }; diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index 6ef60030f0..7c310a7b23 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -1877,37 +1877,22 @@ bool wxAuiToolBar::Realize() // calculate hint sizes for both horizontal and vertical // in the order that leaves toolbar in correct final state - bool retval = false; if (m_orientation == wxHORIZONTAL) { - if (RealizeHelper(dc, false)) - { - m_vertHintSize = GetSize(); - if (RealizeHelper(dc, true)) - { - m_horzHintSize = GetSize(); - retval = true; - } - } + m_vertHintSize = RealizeHelper(dc, false); + m_horzHintSize = RealizeHelper(dc, true); } else { - if (RealizeHelper(dc, true)) - { - m_horzHintSize = GetSize(); - if (RealizeHelper(dc, false)) - { - m_vertHintSize = GetSize(); - retval = true; - } - } + m_horzHintSize = RealizeHelper(dc, true); + m_vertHintSize = RealizeHelper(dc, false); } Refresh(false); - return retval; + return true; } -bool wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) +wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) { // Remove old sizer before adding any controls in this tool bar, which are // elements of this sizer, to the new sizer below. @@ -2149,7 +2134,7 @@ bool wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) m_sizer->SetDimension(0, 0, curSize.x, curSize.y); } - return true; + return GetSize(); } int wxAuiToolBar::GetOverflowState() const From 8f822d3c592852b37d3d6c794e555c1f7aef5cf5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 17:51:05 +0100 Subject: [PATCH 107/257] Simplify adding spacers in wxAuiToolBar::RealizeHelper() There is no need to test for the orientation explicitly, as we can just call AddSpacer() and pass it the spacer size in the direction of the sizer (which is what we always need). No real changes, just make the code simpler and nicer to read. --- src/aui/auibar.cpp | 38 ++++++++++---------------------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index 7c310a7b23..bd3c88e415 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -1907,10 +1907,8 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) int gripperSize = m_art->GetElementSize(wxAUI_TBART_GRIPPER_SIZE); if (gripperSize > 0 && m_gripperVisible) { - if (horizontal) - m_gripperSizerItem = sizer->Add(gripperSize, 1, 0, wxEXPAND); - else - m_gripperSizerItem = sizer->Add(1, gripperSize, 0, wxEXPAND); + m_gripperSizerItem = sizer->AddSpacer(gripperSize); + m_gripperSizerItem->SetFlag(wxEXPAND); } else { @@ -1920,10 +1918,7 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) // add "left" padding if (m_leftPadding > 0) { - if (horizontal) - sizer->Add(m_leftPadding, 1); - else - sizer->Add(1, m_leftPadding); + sizer->AddSpacer(m_leftPadding); } size_t i, count; @@ -1969,10 +1964,8 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) case wxITEM_SEPARATOR: { - if (horizontal) - sizerItem = sizer->Add(separatorSize, 1, 0, wxEXPAND); - else - sizerItem = sizer->Add(1, separatorSize, 0, wxEXPAND); + sizerItem = sizer->AddSpacer(separatorSize); + sizerItem->SetFlag(wxEXPAND); // add tool packing if (i+1 < count) @@ -2039,10 +2032,7 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) // add "right" padding if (m_rightPadding > 0) { - if (horizontal) - sizer->Add(m_rightPadding, 1); - else - sizer->Add(1, m_rightPadding); + sizer->AddSpacer(m_rightPadding); } // add drop down area @@ -2053,10 +2043,8 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) int overflow_size = m_art->GetElementSize(wxAUI_TBART_OVERFLOW_SIZE); if (overflow_size > 0 && m_overflowVisible) { - if (horizontal) - m_overflowSizerItem = sizer->Add(overflow_size, 1, 0, wxEXPAND); - else - m_overflowSizerItem = sizer->Add(1, overflow_size, 0, wxEXPAND); + m_overflowSizerItem = sizer->AddSpacer(overflow_size); + m_overflowSizerItem->SetFlag(wxEXPAND); m_overflowSizerItem->SetMinSize(m_overflowSizerItem->GetSize()); } else @@ -2072,10 +2060,7 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) // add "top" padding if (m_topPadding > 0) { - if (horizontal) - outside_sizer->Add(1, m_topPadding); - else - outside_sizer->Add(m_topPadding, 1); + outside_sizer->AddSpacer(m_topPadding); } // add the sizer that contains all of the toolbar elements @@ -2084,10 +2069,7 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) // add "bottom" padding if (m_bottomPadding > 0) { - if (horizontal) - outside_sizer->Add(1, m_bottomPadding); - else - outside_sizer->Add(m_bottomPadding, 1); + outside_sizer->AddSpacer(m_bottomPadding); } m_sizer = outside_sizer; From c53fc91cd6771dcc4b0712391d30c17205073816 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 17:52:31 +0100 Subject: [PATCH 108/257] Pass wxOrientation and not bool to wxAuiToolBar::RealizeHelper() This makes the code more readable and also simpler as RealizeHelper() only used its boolean parameter to convert it to wxOrientation anyhow after the changes of the parent commit. No real changes. --- include/wx/aui/auibar.h | 2 +- src/aui/auibar.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/include/wx/aui/auibar.h b/include/wx/aui/auibar.h index b85c85fdf0..8d1a0276f7 100644 --- a/include/wx/aui/auibar.h +++ b/include/wx/aui/auibar.h @@ -704,7 +704,7 @@ private: // Common part of OnLeaveWindow() and OnCaptureLost(). void DoResetMouseState(); - wxSize RealizeHelper(wxClientDC& dc, bool horizontal); + wxSize RealizeHelper(wxClientDC& dc, wxOrientation orientation); wxDECLARE_EVENT_TABLE(); wxDECLARE_CLASS(wxAuiToolBar); diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index bd3c88e415..2a4e34b419 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -1879,20 +1879,20 @@ bool wxAuiToolBar::Realize() // in the order that leaves toolbar in correct final state if (m_orientation == wxHORIZONTAL) { - m_vertHintSize = RealizeHelper(dc, false); - m_horzHintSize = RealizeHelper(dc, true); + m_vertHintSize = RealizeHelper(dc, wxVERTICAL); + m_horzHintSize = RealizeHelper(dc, wxHORIZONTAL); } else { - m_horzHintSize = RealizeHelper(dc, true); - m_vertHintSize = RealizeHelper(dc, false); + m_horzHintSize = RealizeHelper(dc, wxHORIZONTAL); + m_vertHintSize = RealizeHelper(dc, wxVERTICAL); } Refresh(false); return true; } -wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) +wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, wxOrientation orientation) { // Remove old sizer before adding any controls in this tool bar, which are // elements of this sizer, to the new sizer below. @@ -1900,7 +1900,7 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) m_sizer = nullptr; // create the new sizer to add toolbar elements to - wxBoxSizer* sizer = new wxBoxSizer(horizontal ? wxHORIZONTAL : wxVERTICAL); + wxBoxSizer* sizer = new wxBoxSizer(orientation); // add gripper area int separatorSize = m_art->GetElementSize(wxAUI_TBART_SEPARATOR_SIZE); @@ -2055,7 +2055,7 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, bool horizontal) // the outside sizer helps us apply the "top" and "bottom" padding - wxBoxSizer* outside_sizer = new wxBoxSizer(horizontal ? wxVERTICAL : wxHORIZONTAL); + wxBoxSizer* outside_sizer = new wxBoxSizer(orientation ^ wxBOTH); // add "top" padding if (m_topPadding > 0) From a2a8fc1d65d4a00136e9bbf209ce71f408005749 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 17:56:10 +0100 Subject: [PATCH 109/257] Avoid harmless MSVC shadowing warning in the test Using "argc" and "argv" for parameter names triggers C4458 with MSVS 2022, warning about hiding class members with the same names. As we can't rename the latter, rename the parameters to avoid this. --- tests/test.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test.cpp b/tests/test.cpp index 1111b7cd30..9e37f1da5d 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -364,10 +364,10 @@ public: return !wxGetEnv(wxASCII_STR("WX_TEST_DISABLE_GUI"), nullptr); } - virtual bool Initialize(int& argc, wxChar **argv) override + virtual bool Initialize(int& argcIn, wxChar **argvIn) override { - return IsGUIEnabled() ? wxApp::Initialize(argc, argv) - : wxAppConsole::Initialize(argc, argv); + return IsGUIEnabled() ? wxApp::Initialize(argcIn, argvIn) + : wxAppConsole::Initialize(argcIn, argvIn); } virtual bool OnInitGui() override From de4c0af40213fe00cdec49a7f3836ea1938cad08 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 20:46:16 +0100 Subject: [PATCH 110/257] Don't duplicate GetClientSize() call No real changes, just remove a duplicated line. --- src/aui/auibar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index 2a4e34b419..469f173595 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -2097,9 +2097,10 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, wxOrientation orientation) m_minWidth = size.x; m_minHeight = size.y; + wxSize curSize = GetClientSize(); + if ((m_windowStyle & wxAUI_TB_NO_AUTORESIZE) == 0) { - wxSize curSize = GetClientSize(); wxSize new_size = GetMinSize(); if (new_size != curSize) { @@ -2112,7 +2113,6 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, wxOrientation orientation) } else { - wxSize curSize = GetClientSize(); m_sizer->SetDimension(0, 0, curSize.x, curSize.y); } From d85e26434c8f7dd56fb380b1b88df8f717eb7d04 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 20:54:16 +0100 Subject: [PATCH 111/257] Avoid resizing wxAuiToolBar to size in the wrong orientation This is unnecessary and resulted in sometimes visible flicker, when the wrong shape of the toolbar could be temporarily seen on screen before it was replaced with the correct one. Only set the actual window size in Realize(), and do it only for the current orientation, instead of doing it in RealizeHelper() which is called for both the current orientation and the transversal one. Closes #24023. --- src/aui/auibar.cpp | 57 ++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index 469f173595..1d3390aaf9 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -1875,17 +1875,44 @@ bool wxAuiToolBar::Realize() if (!dc.IsOk()) return false; - // calculate hint sizes for both horizontal and vertical - // in the order that leaves toolbar in correct final state + // calculate hint sizes for both horizontal and vertical orientations and + // store the size appropriate for the current orientation in this variable. + wxSize size; if (m_orientation == wxHORIZONTAL) { m_vertHintSize = RealizeHelper(dc, wxVERTICAL); m_horzHintSize = RealizeHelper(dc, wxHORIZONTAL); + + size = m_horzHintSize; } else { m_horzHintSize = RealizeHelper(dc, wxHORIZONTAL); m_vertHintSize = RealizeHelper(dc, wxVERTICAL); + + size = m_vertHintSize; + } + + // set control size + m_minWidth = size.x; + m_minHeight = size.y; + + wxSize curSize = GetClientSize(); + + if ((m_windowStyle & wxAUI_TB_NO_AUTORESIZE) == 0) + { + if (size != curSize) + { + SetClientSize(size); + } + else + { + m_sizer->SetDimension(0, 0, curSize.x, curSize.y); + } + } + else + { + m_sizer->SetDimension(0, 0, curSize.x, curSize.y); } Refresh(false); @@ -2092,31 +2119,7 @@ wxSize wxAuiToolBar::RealizeHelper(wxClientDC& dc, wxOrientation orientation) item.m_sizerItem->SetMinSize(item.m_minSize); } - // set control size - wxSize size = m_sizer->GetMinSize(); - m_minWidth = size.x; - m_minHeight = size.y; - - wxSize curSize = GetClientSize(); - - if ((m_windowStyle & wxAUI_TB_NO_AUTORESIZE) == 0) - { - wxSize new_size = GetMinSize(); - if (new_size != curSize) - { - SetClientSize(new_size); - } - else - { - m_sizer->SetDimension(0, 0, curSize.x, curSize.y); - } - } - else - { - m_sizer->SetDimension(0, 0, curSize.x, curSize.y); - } - - return GetSize(); + return m_sizer->GetMinSize(); } int wxAuiToolBar::GetOverflowState() const From 7ea528b280560f4c1fda4afee830e480e8aaae40 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 20:57:09 +0100 Subject: [PATCH 112/257] Simplify wxAuiToolBar resizing code a bit more No real changes, just remove a duplicate call to wxSizer::SetDimension() too and call it only once. Also add some comments to explain what's going on here. --- src/aui/auibar.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index 1d3390aaf9..5e166dbdb3 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -1893,24 +1893,19 @@ bool wxAuiToolBar::Realize() size = m_vertHintSize; } - // set control size + // Remember our minimum size. m_minWidth = size.x; m_minHeight = size.y; + // And set control size if we are not forbidden from doing it by the use of + // a special flag and if it did actually change. wxSize curSize = GetClientSize(); - if ((m_windowStyle & wxAUI_TB_NO_AUTORESIZE) == 0) + if ((m_windowStyle & wxAUI_TB_NO_AUTORESIZE) == 0 && (size != curSize)) { - if (size != curSize) - { - SetClientSize(size); - } - else - { - m_sizer->SetDimension(0, 0, curSize.x, curSize.y); - } + SetClientSize(size); } - else + else // Don't change the size but let the sizer know about available size. { m_sizer->SetDimension(0, 0, curSize.x, curSize.y); } From 400ce8b5828802e466c29b864512b476c2bce7f4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 21:17:17 +0100 Subject: [PATCH 113/257] Return null from wxGetX11Display() when using Wayland Returning Wayland display pointer as XDisplay was really confusing and resulted in more weird crashes than just using null pointer directly. --- include/wx/utils.h | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/include/wx/utils.h b/include/wx/utils.h index f63215f5b3..47c5e356e6 100644 --- a/include/wx/utils.h +++ b/include/wx/utils.h @@ -763,19 +763,24 @@ void WXDLLIMPEXP_CORE wxGetMousePosition( int* x, int* y ); wxDisplayType type; }; WXDLLIMPEXP_CORE wxDisplayInfo wxGetDisplayInfo(); + + inline struct _XDisplay *wxGetX11Display() + { + const auto& info = wxGetDisplayInfo(); + return info.type == wxDisplayX11 ? (_XDisplay*)info.dpy : nullptr; + } #endif #ifdef __X__ WXDLLIMPEXP_CORE WXDisplay *wxGetDisplay(); WXDLLIMPEXP_CORE bool wxSetDisplay(const wxString& display_name); WXDLLIMPEXP_CORE wxString wxGetDisplayName(); -#endif // X or GTK+ -// use this function instead of the functions above in implementation code -inline struct _XDisplay *wxGetX11Display() -{ - return (_XDisplay *)wxGetDisplay(); -} + inline struct _XDisplay *wxGetX11Display() + { + return (_XDisplay *)wxGetDisplay(); + } +#endif // X #endif // X11 || wxGTK From 438e21623617bb05424d40880e3dec7e1adc6698 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 21:52:01 +0100 Subject: [PATCH 114/257] Don't compute unnecessary hint sizes in unsupported direction For the toolbars locked in one direction there is no need to compute the hint size in the other one, so don't bother calling RealizeHelper() for the non-current orientation in this case. This is just a small optimization. --- src/aui/auibar.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/aui/auibar.cpp b/src/aui/auibar.cpp index 5e166dbdb3..91fe377cb7 100644 --- a/src/aui/auibar.cpp +++ b/src/aui/auibar.cpp @@ -1875,19 +1875,24 @@ bool wxAuiToolBar::Realize() if (!dc.IsOk()) return false; - // calculate hint sizes for both horizontal and vertical orientations and + // calculate hint sizes for both horizontal and vertical orientations if we + // can use them, i.e. if the toolbar isn't locked into just one of them, and // store the size appropriate for the current orientation in this variable. wxSize size; if (m_orientation == wxHORIZONTAL) { - m_vertHintSize = RealizeHelper(dc, wxVERTICAL); + if (!HasFlag(wxAUI_TB_HORIZONTAL)) + m_vertHintSize = RealizeHelper(dc, wxVERTICAL); + m_horzHintSize = RealizeHelper(dc, wxHORIZONTAL); size = m_horzHintSize; } else { - m_horzHintSize = RealizeHelper(dc, wxHORIZONTAL); + if (!HasFlag(wxAUI_TB_VERTICAL)) + m_horzHintSize = RealizeHelper(dc, wxHORIZONTAL); + m_vertHintSize = RealizeHelper(dc, wxVERTICAL); size = m_vertHintSize; From e55d7c1dc354ab8f2cb1a27c0c4ab4aede6a40ad Mon Sep 17 00:00:00 2001 From: DjPasco Date: Thu, 2 Feb 2023 17:23:36 +0200 Subject: [PATCH 115/257] Scroll by entire rows in wxGrid when they have uniform heights Set vertical scroll line size to the default row height. See #23032. --- src/generic/grid.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 36bd8dbdc8..44b476ec0a 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -2789,6 +2789,10 @@ void wxGrid::InitPixelFields() m_defaultRowHeight += 4; #endif + // Scroll by row height to avoid showing partial rows when all heights are + // the same. + m_yScrollPixelsPerLine = m_defaultRowHeight; + // Don't change the value when called from OnDPIChanged() later if the // corresponding label window is hidden, these values should remain zeroes // then. From ffe15b2fa6b0a6f56499e5f0a075424caa29630d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Dec 2023 03:38:08 +0100 Subject: [PATCH 116/257] Enable wxAUI_MGR_LIVE_RESIZE by default This makes behaviour more consistent across all platforms, as this flag is always used in wxGTK and wxOSX, and might avoid some problems in wxMSW, see #23982. --- include/wx/aui/framemanager.h | 3 ++- interface/wx/aui/framemanager.h | 10 ++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/include/wx/aui/framemanager.h b/include/wx/aui/framemanager.h index da9dff9609..167c486c35 100644 --- a/include/wx/aui/framemanager.h +++ b/include/wx/aui/framemanager.h @@ -51,7 +51,8 @@ enum wxAuiManagerOption wxAUI_MGR_DEFAULT = wxAUI_MGR_ALLOW_FLOATING | wxAUI_MGR_TRANSPARENT_HINT | wxAUI_MGR_HINT_FADE | - wxAUI_MGR_NO_VENETIAN_BLINDS_FADE + wxAUI_MGR_NO_VENETIAN_BLINDS_FADE | + wxAUI_MGR_LIVE_RESIZE }; diff --git a/interface/wx/aui/framemanager.h b/interface/wx/aui/framemanager.h index 359aecfc04..549492f354 100644 --- a/interface/wx/aui/framemanager.h +++ b/interface/wx/aui/framemanager.h @@ -45,12 +45,14 @@ enum wxAuiManagerOption wxAUI_MGR_NO_VENETIAN_BLINDS_FADE = 1 << 7, /// When a docked pane is resized, its content is refreshed in live (instead of moving /// the border alone and refreshing the content at the end). + /// Since wxWidgets 3.3.0 this flag is included in the default flags. wxAUI_MGR_LIVE_RESIZE = 1 << 8, /// Default behaviour. wxAUI_MGR_DEFAULT = wxAUI_MGR_ALLOW_FLOATING | wxAUI_MGR_TRANSPARENT_HINT | wxAUI_MGR_HINT_FADE | - wxAUI_MGR_NO_VENETIAN_BLINDS_FADE + wxAUI_MGR_NO_VENETIAN_BLINDS_FADE | + wxAUI_MGR_LIVE_RESIZE }; /** @@ -142,7 +144,11 @@ enum wxAuiManagerOption docking hint immediately. @style{wxAUI_MGR_LIVE_RESIZE} When a docked pane is resized, its content is refreshed in live (instead of moving - the border alone and refreshing the content at the end). + the border alone and refreshing the content at the end). Note that + this flag is included in wxAUI_MGR_DEFAULT and so needs to be + explicitly turned off if you don't need. Also note that it is + always enabled in wxGTK3 and wxOSX ports as non-live resizing is not + implemented in them. @style{wxAUI_MGR_DEFAULT} Default behaviour, combines: wxAUI_MGR_ALLOW_FLOATING | wxAUI_MGR_TRANSPARENT_HINT | wxAUI_MGR_HINT_FADE | wxAUI_MGR_NO_VENETIAN_BLINDS_FADE. From ed4425bf6ec8a115f5811ae99865164802763b31 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Wed, 13 Dec 2023 22:59:38 +0100 Subject: [PATCH 117/257] Remove unreferenced defines from wxQt code base --- src/qt/window.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/qt/window.cpp b/src/qt/window.cpp index a4a85383a9..7d1b996d91 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -35,8 +35,6 @@ #include "wx/qt/private/compat.h" #include "wx/qt/private/winevent.h" -#define VERT_SCROLLBAR_POSITION 0, 1 -#define HORZ_SCROLLBAR_POSITION 1, 0 #define TRACE_QT_WINDOW "qtwindow" From 1a7f1ccc85d1cda6f4ccbc987484b7357f6ce745 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Wed, 13 Dec 2023 23:03:37 +0100 Subject: [PATCH 118/257] Add missing override to wxQtEventSignalHandler --- include/wx/qt/private/winevent.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/wx/qt/private/winevent.h b/include/wx/qt/private/winevent.h index f4db66dfd0..79734ded16 100644 --- a/include/wx/qt/private/winevent.h +++ b/include/wx/qt/private/winevent.h @@ -371,7 +371,7 @@ protected: virtual bool winEvent ( MSG * message, long * result ) { } virtual bool x11Event ( XEvent * event ) { } */ - virtual bool event(QEvent *event) + virtual bool event(QEvent *event) override { if (event->type() == QEvent::Gesture) { From cace95f4d38ed859b582f2cbf8e12688f77d2e55 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Wed, 13 Dec 2023 23:15:09 +0100 Subject: [PATCH 119/257] Stop using QScrollArea as a central widget of a wxFrame under wxQt There's really no need to make the wxFrame itself scrollable as it unnecessarily complicates the implementation and introduces annoying bugs like content shifted by 1px. Moreover, the scrolling logic is already encapsulated in other widgets like wxScrolledWindow which can be used as a hosting container in the frame to handle scrolling. --- src/qt/frame.cpp | 67 +++++++++++++----------------------------------- 1 file changed, 18 insertions(+), 49 deletions(-) diff --git a/src/qt/frame.cpp b/src/qt/frame.cpp index 7dedebf4f8..f47a4bab03 100644 --- a/src/qt/frame.cpp +++ b/src/qt/frame.cpp @@ -26,18 +26,25 @@ class wxQtMainWindow : public wxQtEventSignalHandler< QMainWindow, wxFrame > { public: - wxQtMainWindow( wxWindow *parent, wxFrame *handler ); + wxQtMainWindow( wxWindow *parent, wxFrame *handler ) + : wxQtEventSignalHandler< QMainWindow, wxFrame >( parent, handler ) + { + } private: virtual bool focusNextPrevChild(bool) override { return false; } }; -// Central widget helper (container to show scroll bars and receive events): +// Central widget helper (container which receives events): -class wxQtCentralWidget : public wxQtEventSignalHandler< QScrollArea, wxFrame > +class wxQtCentralWidget : public wxQtEventSignalHandler< QWidget, wxFrame > { - public: - wxQtCentralWidget( wxWindow *parent, wxFrame *handler ); +public: + wxQtCentralWidget( wxWindow *parent, wxFrame *handler ) + : wxQtEventSignalHandler< QWidget, wxFrame >( parent, handler ) + { + setFocusPolicy(Qt::NoFocus); + } }; @@ -52,10 +59,10 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString& title, { m_qtWindow = new wxQtMainWindow( parent, this ); - // TODO: Could we use a wxPanel as the central widget? If so then we could - // remove wxWindow::QtReparent. - - GetQMainWindow()->setCentralWidget( new wxQtCentralWidget( parent, this ) ); + // QMainWindow takes ownership of the central widget pointer. + // Not using QScrollArea or wxPanel is intentional here as it makes the + // implementation simpler and manageable. + GetQMainWindow()->setCentralWidget( new wxQtCentralWidget( this, this ) ); if ( !wxFrameBase::Create( parent, id, title, pos, size, style, name ) ) return false; @@ -205,45 +212,21 @@ void wxFrame::RemoveChild( wxWindowBase *child ) QScrollArea *wxFrame::QtGetScrollBarsContainer() const { - return dynamic_cast (GetQMainWindow()->centralWidget() ); + return nullptr; } // get the origin of the client area in the client coordinates // excluding any menubar and toolbar if any. wxPoint wxFrame::GetClientAreaOrigin() const { - wxPoint pt = wxTopLevelWindow::GetClientAreaOrigin(); + wxPoint pt = wxFrameBase::GetClientAreaOrigin(); - // It seems that Qt always adds 1px border around QMainWindow, - // being resizable or not, so account for it here. - pt += wxPoint(1, 1); - -#ifndef __WXUNIVERSAL__ #if wxUSE_MENUBAR wxMenuBar * const menubar = GetMenuBar(); if ( menubar && menubar->IsAttached() ) pt.y += menubar->GetSize().y; #endif // wxUSE_MENUBAR -#if wxUSE_TOOLBAR - wxToolBar * const toolbar = GetToolBar(); - if ( toolbar && toolbar->IsShown() ) - { - const wxSize sizeTB = toolbar->GetSize(); - const int directionTB = toolbar->GetDirection(); - - if ( directionTB == wxTB_TOP ) - { - pt.y += sizeTB.y; - } - else if ( directionTB == wxTB_LEFT ) - { - pt.x += sizeTB.x; - } - } -#endif // wxUSE_TOOLBAR -#endif // __WXUNIVERSAL__ - return pt; } @@ -284,17 +267,3 @@ QMainWindow *wxFrame::GetQMainWindow() const { return static_cast(m_qtWindow); } - -//============================================================================= - -wxQtMainWindow::wxQtMainWindow( wxWindow *parent, wxFrame *handler ) - : wxQtEventSignalHandler< QMainWindow, wxFrame >( parent, handler ) -{ -// setCentralWidget( new wxQtWidget( parent, handler )); -} - -wxQtCentralWidget::wxQtCentralWidget( wxWindow *parent, wxFrame *handler ) - : wxQtEventSignalHandler< QScrollArea, wxFrame >( parent, handler ) -{ - setFocusPolicy(Qt::NoFocus); -} From 5fe4bb90d387ce1d4903f934354fe8dc9fc5c8f1 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 14 Dec 2023 00:09:05 +0100 Subject: [PATCH 120/257] Fix handling paint events under wxQt after the last commit Qt doesn't allow painting on a widget from a handler of another widget --- src/qt/window.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qt/window.cpp b/src/qt/window.cpp index 7d1b996d91..19206555b5 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -1286,7 +1286,8 @@ bool wxWindowQt::QtHandlePaintEvent ( QWidget *handler, QPaintEvent *event ) * for the client area (the scrolled part). Events for the whole window * (including scrollbars and maybe status or menu bars are handled by Qt */ - if ( QtGetScrollBarsContainer() && handler != QtGetScrollBarsContainer() ) + if ( (QtGetScrollBarsContainer() && + QtGetScrollBarsContainer() != handler) || handler != GetHandle() ) { return false; } From d1be2f42d6c83e9787b9f817096ba139ee7a2788 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 14 Dec 2023 00:19:30 +0100 Subject: [PATCH 121/257] Get rid of unnecessary else statement in QtHandlePaintEvent --- src/qt/window.cpp | 176 +++++++++++++++++++++++----------------------- 1 file changed, 87 insertions(+), 89 deletions(-) diff --git a/src/qt/window.cpp b/src/qt/window.cpp index 19206555b5..f42fe3de89 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -1291,110 +1291,108 @@ bool wxWindowQt::QtHandlePaintEvent ( QWidget *handler, QPaintEvent *event ) { return false; } - else + + // use the Qt event region: + m_updateRegion.QtSetRegion( event->region() ); + + // Prepare the Qt painter for wxWindowDC: + bool ok = false; + if ( QtGetScrollBarsContainer() ) { - // use the Qt event region: - m_updateRegion.QtSetRegion( event->region() ); + // QScrollArea can only draw in the viewport: + ok = m_qtPainter->begin( QtGetScrollBarsContainer()->viewport() ); + } + if ( !ok ) + { + // Start the paint in the widget itself + ok = m_qtPainter->begin( GetHandle() ); + } - // Prepare the Qt painter for wxWindowDC: - bool ok = false; - if ( QtGetScrollBarsContainer() ) - { - // QScrollArea can only draw in the viewport: - ok = m_qtPainter->begin( QtGetScrollBarsContainer()->viewport() ); - } - if ( !ok ) - { - // Start the paint in the widget itself - ok = m_qtPainter->begin( GetHandle() ); - } + if ( ok ) + { + bool handled; - if ( ok ) + if ( !m_qtPicture ) { - bool handled; - - if ( !m_qtPicture ) + // Real paint event (not for wxClientDC), prepare the background + switch ( GetBackgroundStyle() ) { - // Real paint event (not for wxClientDC), prepare the background - switch ( GetBackgroundStyle() ) - { - case wxBG_STYLE_TRANSPARENT: - if (IsTransparentBackgroundSupported()) - { - // Set a transparent background, so that overlaying in parent - // might indeed let see through where this child did not - // explicitly paint. See wxBG_STYLE_SYSTEM for more comment - } - break; - case wxBG_STYLE_ERASE: - { - // the background should be cleared by qt auto fill - // send the erase event (properly creating a DC for it) - wxPaintDC dc( this ); - dc.SetDeviceClippingRegion( m_updateRegion ); + case wxBG_STYLE_TRANSPARENT: + if (IsTransparentBackgroundSupported()) + { + // Set a transparent background, so that overlaying in parent + // might indeed let see through where this child did not + // explicitly paint. See wxBG_STYLE_SYSTEM for more comment + } + break; + case wxBG_STYLE_ERASE: + { + // the background should be cleared by qt auto fill + // send the erase event (properly creating a DC for it) + wxPaintDC dc( this ); + dc.SetDeviceClippingRegion( m_updateRegion ); - wxEraseEvent erase( GetId(), &dc ); - erase.SetEventObject(this); - if ( ProcessWindowEvent(erase) ) - { - // background erased, don't do it again - break; - } - // Ensure DC is cleared if handler didn't and Qt will not do it - if ( UseBgCol() && !GetHandle()->autoFillBackground() ) - { - wxLogTrace(TRACE_QT_WINDOW, wxT("wxWindow::QtHandlePaintEvent %s clearing DC to %s"), - GetName(), GetBackgroundColour().GetAsString() - ); - dc.SetBackground(GetBackgroundColour()); - dc.Clear(); - } - } - wxFALLTHROUGH; - case wxBG_STYLE_SYSTEM: - if ( GetThemeEnabled() ) + wxEraseEvent erase( GetId(), &dc ); + erase.SetEventObject(this); + if ( ProcessWindowEvent(erase) ) { - // let qt render the background: - // commented out as this will cause recursive painting - // this should be done outside using setBackgroundRole - // setAutoFillBackground or setAttribute - //wxWindowDC dc( (wxWindow*)this ); - //widget->render(m_qtPainter); + // background erased, don't do it again + break; } - break; - case wxBG_STYLE_PAINT: - // nothing to do: window will be painted over in EVT_PAINT - break; + // Ensure DC is cleared if handler didn't and Qt will not do it + if ( UseBgCol() && !GetHandle()->autoFillBackground() ) + { + wxLogTrace(TRACE_QT_WINDOW, wxT("wxWindow::QtHandlePaintEvent %s clearing DC to %s"), + GetName(), GetBackgroundColour().GetAsString() + ); + dc.SetBackground(GetBackgroundColour()); + dc.Clear(); + } + } + wxFALLTHROUGH; + case wxBG_STYLE_SYSTEM: + if ( GetThemeEnabled() ) + { + // let qt render the background: + // commented out as this will cause recursive painting + // this should be done outside using setBackgroundRole + // setAutoFillBackground or setAttribute + //wxWindowDC dc( (wxWindow*)this ); + //widget->render(m_qtPainter); + } + break; + case wxBG_STYLE_PAINT: + // nothing to do: window will be painted over in EVT_PAINT + break; - case wxBG_STYLE_COLOUR: - wxFAIL_MSG( "unsupported background style" ); - } - - // send the paint event (wxWindowDC will draw directly): - wxPaintEvent paint( this ); - handled = ProcessWindowEvent(paint); - m_updateRegion.Clear(); - } - else - { - // Data from wxClientDC, paint it - m_qtPicture->play( m_qtPainter.get() ); - // Reset picture - m_qtPicture.reset(); - handled = true; + case wxBG_STYLE_COLOUR: + wxFAIL_MSG( "unsupported background style" ); } - // commit changes of the painter to the widget - m_qtPainter->end(); - - return handled; + // send the paint event (wxWindowDC will draw directly): + wxPaintEvent paint( this ); + handled = ProcessWindowEvent(paint); + m_updateRegion.Clear(); } else { - // Painter didn't begun, not handled by wxWidgets: - wxLogTrace(TRACE_QT_WINDOW, wxT("wxWindow::QtHandlePaintEvent %s Qt widget painter begin failed"), GetName() ); - return false; + // Data from wxClientDC, paint it + m_qtPicture->play( m_qtPainter.get() ); + // Reset picture + m_qtPicture.reset(); + handled = true; } + + // commit changes of the painter to the widget + m_qtPainter->end(); + + return handled; + } + else + { + // Painter didn't begun, not handled by wxWidgets: + wxLogTrace(TRACE_QT_WINDOW, wxT("wxWindow::QtHandlePaintEvent %s Qt widget painter begin failed"), GetName() ); + return false; } } From 6a76e7a610e7b21810b56fc4df4952ad137abb29 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 14 Dec 2023 00:24:39 +0100 Subject: [PATCH 122/257] Fix wxPaintDC under wxQt after the last commits The {menu,tool,status} bars will not be painted correctly otherwise. --- include/wx/qt/dcclient.h | 2 +- src/qt/dcclient.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/wx/qt/dcclient.h b/include/wx/qt/dcclient.h index 788c4867ba..dc382d4f7c 100644 --- a/include/wx/qt/dcclient.h +++ b/include/wx/qt/dcclient.h @@ -46,7 +46,7 @@ private: }; -class WXDLLIMPEXP_CORE wxPaintDCImpl : public wxClientDCImpl +class WXDLLIMPEXP_CORE wxPaintDCImpl : public wxWindowDCImpl { public: wxPaintDCImpl( wxDC *owner ); diff --git a/src/qt/dcclient.cpp b/src/qt/dcclient.cpp index c4f9a23a6e..5327ccfccc 100644 --- a/src/qt/dcclient.cpp +++ b/src/qt/dcclient.cpp @@ -116,15 +116,15 @@ wxClientDCImpl::wxClientDCImpl( wxDC *owner, wxWindow *win ) //############################################################################## -wxIMPLEMENT_CLASS(wxPaintDCImpl,wxClientDCImpl); +wxIMPLEMENT_CLASS(wxPaintDCImpl,wxWindowDCImpl); wxPaintDCImpl::wxPaintDCImpl( wxDC *owner ) - : wxClientDCImpl( owner ) + : wxWindowDCImpl( owner ) { } wxPaintDCImpl::wxPaintDCImpl( wxDC *owner, wxWindow *win ) - : wxClientDCImpl( owner, win ) + : wxWindowDCImpl( owner, win ) { wxCHECK_RET( m_isWindowPainter, "wxPaintDC can't be created outside wxEVT_PAINT handler" ); From d44408d4480c801453af3f419837946f217a84e1 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 14 Dec 2023 01:12:25 +0100 Subject: [PATCH 123/257] Fix wxScrollWindow not scrolling by mouse dragging under wxQt Get rid of wxQtInternalScrollBar and use QScrollArea's scrollbars instead. --- include/wx/qt/window.h | 4 -- src/qt/window.cpp | 113 ++++++++++++++++------------------------- 2 files changed, 43 insertions(+), 74 deletions(-) diff --git a/include/wx/qt/window.h b/include/wx/qt/window.h index acbd9b6fce..9ebbc7e181 100644 --- a/include/wx/qt/window.h +++ b/include/wx/qt/window.h @@ -231,16 +231,12 @@ private: void Init(); QScrollArea *m_qtContainer; // either nullptr or the same as m_qtWindow pointer - QScrollBar *m_horzScrollBar; // owned by m_qtWindow when allocated - QScrollBar *m_vertScrollBar; // owned by m_qtWindow when allocated - // Return the viewport of m_qtContainer, if it's used, or just m_qtWindow. // // Always returns non-null pointer if the window has been already created. QWidget *QtGetClientWidget() const; QScrollBar *QtGetScrollBar( int orientation ) const; - QScrollBar *QtSetScrollBar( int orientation, QScrollBar *scrollBar=nullptr ); bool QtSetBackgroundStyle(); diff --git a/src/qt/window.cpp b/src/qt/window.cpp index f42fe3de89..2fd3f333dd 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -59,11 +59,28 @@ public: wxQtScrollArea(wxWindowQt *parent, wxWindowQt *handler); bool event(QEvent *e) override; + + void OnActionTriggered(int action); + void OnSliderReleased(); }; wxQtScrollArea::wxQtScrollArea( wxWindowQt *parent, wxWindowQt *handler ) : wxQtEventSignalHandler< QScrollArea, wxWindowQt >( parent, handler ) { + auto sb = horizontalScrollBar(); + if ( sb ) + { + connect( sb, &QScrollBar::actionTriggered, this, &wxQtScrollArea::OnActionTriggered ); + connect( sb, &QScrollBar::sliderReleased, this, &wxQtScrollArea::OnSliderReleased ); + } + + sb = verticalScrollBar(); + + if ( sb ) + { + connect( sb, &QScrollBar::actionTriggered, this, &wxQtScrollArea::OnActionTriggered ); + connect( sb, &QScrollBar::sliderReleased, this, &wxQtScrollArea::OnSliderReleased ); + } } bool wxQtScrollArea::event(QEvent *e) @@ -109,29 +126,7 @@ bool wxQtScrollArea::event(QEvent *e) return QScrollArea::event(e); } -class wxQtInternalScrollBar : public wxQtEventSignalHandler< QScrollBar, wxWindowQt > -{ -public: - wxQtInternalScrollBar(wxWindowQt *parent, wxWindowQt *handler ); - ~wxQtInternalScrollBar() - { - disconnect( this, &QScrollBar::actionTriggered, this, &wxQtInternalScrollBar::actionTriggered ); - disconnect( this, &QScrollBar::sliderReleased, this, &wxQtInternalScrollBar::sliderReleased ); - } - void actionTriggered( int action ); - void sliderReleased(); - void valueChanged( int position ); -}; - -wxQtInternalScrollBar::wxQtInternalScrollBar( wxWindowQt *parent, wxWindowQt *handler ) - : wxQtEventSignalHandler< QScrollBar, wxWindowQt >( parent, handler ) -{ - connect( this, &QScrollBar::actionTriggered, this, &wxQtInternalScrollBar::actionTriggered ); - connect( this, &QScrollBar::sliderReleased, this, &wxQtInternalScrollBar::sliderReleased ); -} - - -void wxQtInternalScrollBar::actionTriggered( int action ) +void wxQtScrollArea::OnActionTriggered( int action ) { wxEventType eventType = wxEVT_NULL; switch( action ) @@ -163,17 +158,27 @@ void wxQtInternalScrollBar::actionTriggered( int action ) if ( GetHandler() ) { - wxScrollWinEvent e( eventType, sliderPosition(), wxQtConvertOrientation( orientation() ) ); - EmitEvent( e ); + auto sb = static_cast(sender()); + if ( sb ) + { + wxScrollWinEvent e( eventType, sb->sliderPosition(), + wxQtConvertOrientation( sb->orientation() ) ); + EmitEvent( e ); + } } } -void wxQtInternalScrollBar::sliderReleased() +void wxQtScrollArea::OnSliderReleased() { if ( GetHandler() ) { - wxScrollWinEvent e( wxEVT_SCROLLWIN_THUMBRELEASE, sliderPosition(), wxQtConvertOrientation( orientation() ) ); - EmitEvent( e ); + auto sb = static_cast(sender()); + if ( sb ) + { + wxScrollWinEvent e( wxEVT_SCROLLWIN_THUMBRELEASE, sb->sliderPosition(), + wxQtConvertOrientation( sb->orientation() ) ); + EmitEvent( e ); + } } } @@ -271,9 +276,6 @@ static wxWindowQt *s_capturedWindow = nullptr; void wxWindowQt::Init() { - m_horzScrollBar = nullptr; - m_vertScrollBar = nullptr; - m_qtPainter.reset(new QPainter()); m_mouseInside = false; @@ -356,10 +358,10 @@ bool wxWindowQt::Create( wxWindowQt * parent, wxWindowID id, const wxPoint & pos m_qtContainer = new wxQtScrollArea( parent, this ); m_qtWindow = m_qtContainer; // Create the scroll bars if needed: - if ( style & wxHSCROLL ) - QtSetScrollBar( wxHORIZONTAL ); - if ( style & wxVSCROLL ) - QtSetScrollBar( wxVERTICAL ); + if ( !(style & wxHSCROLL) ) + m_qtContainer->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); + if ( !(style & wxVSCROLL) ) + m_qtContainer->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); } else m_qtWindow = new wxQtWidget( parent, this ); @@ -696,46 +698,18 @@ QWidget *wxWindowQt::QtGetClientWidget() const return qtWidget; } -/* Returns a scrollbar for the given orientation, or nullptr if the scrollbar - * has not been previously created and create is false */ +/* Returns a scrollbar for the given orientation */ QScrollBar *wxWindowQt::QtGetScrollBar( int orientation ) const -{ - QScrollBar *scrollBar = nullptr; - - if ( orientation == wxHORIZONTAL ) - scrollBar = m_horzScrollBar; - else - scrollBar = m_vertScrollBar; - - return scrollBar; -} - -/* Returns a new scrollbar for the given orientation, or set the scrollbar - * passed as parameter */ -QScrollBar *wxWindowQt::QtSetScrollBar( int orientation, QScrollBar *scrollBar ) { QScrollArea *scrollArea = QtGetScrollBarsContainer(); wxCHECK_MSG( scrollArea, nullptr, "Window without scrolling area" ); - // Create a new scrollbar if needed - if ( !scrollBar ) - { - scrollBar = new wxQtInternalScrollBar(this, this); - scrollBar->setOrientation( orientation == wxHORIZONTAL ? Qt::Horizontal : Qt::Vertical ); - } - - // Let Qt handle layout if ( orientation == wxHORIZONTAL ) { - scrollArea->setHorizontalScrollBar( scrollBar ); - m_horzScrollBar = scrollBar; + return scrollArea->horizontalScrollBar(); } - else - { - scrollArea->setVerticalScrollBar( scrollBar ); - m_vertScrollBar = scrollBar; - } - return scrollBar; + + return scrollArea->verticalScrollBar(); } @@ -743,10 +717,9 @@ void wxWindowQt::SetScrollbar( int orientation, int pos, int thumbvisible, int r { wxCHECK_RET(GetHandle(), "Window has not been created"); - //If not exist, create the scrollbar + // may return nullptr if the window is not scrollable in that orientation + // or if it's not scrollable at all. QScrollBar *scrollBar = QtGetScrollBar( orientation ); - if ( scrollBar == nullptr ) - scrollBar = QtSetScrollBar( orientation ); // Configure the scrollbar if it exists. If range is zero we can get here with // scrollBar == nullptr and it is not a problem From a6b3efb2cd07cb62ecf0e812db61f3adb386d3c6 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 14 Dec 2023 01:23:11 +0100 Subject: [PATCH 124/257] Always use live resize for wxAUI under wxQt --- src/aui/framemanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index aa2e448e9f..8a660e0722 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -762,7 +762,7 @@ unsigned int wxAuiManager::GetFlags() const // With Core Graphics on Mac or GTK 3, it's not possible to show sash feedback, // so we'll always use live update instead. -#if defined(__WXMAC__) || defined(__WXGTK3__) +#if defined(__WXMAC__) || defined(__WXGTK3__) || defined(__WXQT__) #define wxUSE_AUI_LIVE_RESIZE_ALWAYS 1 #else #define wxUSE_AUI_LIVE_RESIZE_ALWAYS 0 @@ -3911,7 +3911,7 @@ void wxAuiManager::Render(wxDC* dc) void wxAuiManager::Repaint(wxDC* dc) { -#if defined(__WXMAC__) || defined(__WXGTK3__) +#if defined(__WXMAC__) || defined(__WXGTK3__) || defined(__WXQT__) // We can't use wxClientDC in these ports. if ( dc == nullptr ) { From de2762bc02407eacf2eef37dc077eeda4f1ea423 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 14 Dec 2023 01:28:13 +0100 Subject: [PATCH 125/257] Fix compilation error in auidemo sample under wxQt Also fix ID_NotebookNoCloseButton menu item ui update which causes OnUpdateUI() handler to run forever under wxQt. --- samples/aui/auidemo.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/samples/aui/auidemo.cpp b/samples/aui/auidemo.cpp index 6eeee9a118..5e02b22dd0 100644 --- a/samples/aui/auidemo.cpp +++ b/samples/aui/auidemo.cpp @@ -18,6 +18,7 @@ #include "wx/artprov.h" #include "wx/clipbrd.h" #include "wx/image.h" +#include "wx/choice.h" #include "wx/colordlg.h" #include "wx/wxhtml.h" #include "wx/imaglist.h" @@ -29,6 +30,7 @@ #include "wx/statusbr.h" #include "wx/msgdlg.h" #include "wx/textdlg.h" +#include "wx/stattext.h" #include "wx/aui/aui.h" #include "../sample.xpm" @@ -1261,7 +1263,7 @@ void MyFrame::OnUpdateUI(wxUpdateUIEvent& event) break; case ID_NotebookNoCloseButton: - event.Check((m_notebook_style & (wxAUI_NB_CLOSE_BUTTON|wxAUI_NB_CLOSE_ON_ALL_TABS|wxAUI_NB_CLOSE_ON_ACTIVE_TAB)) != 0); + event.Check((m_notebook_style & (wxAUI_NB_CLOSE_BUTTON|wxAUI_NB_CLOSE_ON_ALL_TABS|wxAUI_NB_CLOSE_ON_ACTIVE_TAB)) == 0); break; case ID_NotebookCloseButton: event.Check((m_notebook_style & wxAUI_NB_CLOSE_BUTTON) != 0); From 484785fb882bf5742466222e9ac5b2b0cd7bbd51 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Thu, 14 Dec 2023 18:06:38 +0100 Subject: [PATCH 126/257] Override {Set,Is}DoubleBuffered() under wxQt Closes #24136. --- include/wx/qt/window.h | 3 +++ src/qt/window.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/include/wx/qt/window.h b/include/wx/qt/window.h index 9ebbc7e181..27eb929b00 100644 --- a/include/wx/qt/window.h +++ b/include/wx/qt/window.h @@ -136,6 +136,9 @@ public: virtual bool SetBackgroundColour(const wxColour& colour) override; virtual bool SetForegroundColour(const wxColour& colour) override; + virtual void SetDoubleBuffered(bool on) override; + virtual bool IsDoubleBuffered() const override; + QWidget *GetHandle() const override; #if wxUSE_DRAG_AND_DROP diff --git a/src/qt/window.cpp b/src/qt/window.cpp index 2fd3f333dd..1f4f008610 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -1253,6 +1253,30 @@ bool wxWindowQt::SetForegroundColour(const wxColour& colour) return true; } +void wxWindowQt::SetDoubleBuffered(bool on) +{ + wxCHECK_RET( GetHandle(), "invalid window" ); + + // Quoting from the Qt docs: + // --------------------------- + // Indicates that the widget wants to draw directly onto the screen. Widgets + // with this attribute set do not participate in composition management, i.e. + // they cannot be semi-transparent or shine through semi-transparent overlapping + // widgets. Note: This flag is only supported on X11 and it disables double buffering. + // On Qt for Embedded Linux, the flag only works when set on a top-level widget and it + // relies on support from the active screen driver. This flag is set or cleared by the + // widget's author. To render outside of Qt's paint system, e.g., if you require native + // painting primitives, you need to reimplement QWidget::paintEngine() to return 0 and + // set this flag. + + GetHandle()->setAttribute(Qt::WA_PaintOnScreen, !on); +} + +bool wxWindowQt::IsDoubleBuffered() const +{ + return !GetHandle()->testAttribute(Qt::WA_PaintOnScreen); +} + bool wxWindowQt::QtHandlePaintEvent ( QWidget *handler, QPaintEvent *event ) { /* If this window has scrollbars, only let wx handle the event if it is From 5fb8a54e14899dad99049e2a4c8901a0075e588c Mon Sep 17 00:00:00 2001 From: ali kettab Date: Fri, 15 Dec 2023 17:18:00 +0100 Subject: [PATCH 127/257] Change the return type of QtGetScrollBarsContainer() under wxQt Neither QListWidget nor QTextEdit derive from QScrollArea and the cast to it is just UB. Instead, using the common base class QAbstractScrollArea is safer and eliminates the need to these dangerous and insidious crosscast'ings. --- include/wx/qt/frame.h | 4 ++-- include/wx/qt/listbox.h | 4 ++-- include/wx/qt/textctrl.h | 4 ++-- include/wx/qt/window.h | 6 +++--- src/qt/dcclient.cpp | 2 +- src/qt/frame.cpp | 3 +-- src/qt/listbox.cpp | 4 ++-- src/qt/textctrl.cpp | 10 +++++----- src/qt/window.cpp | 4 ++-- 9 files changed, 20 insertions(+), 21 deletions(-) diff --git a/include/wx/qt/frame.h b/include/wx/qt/frame.h index 3c1db1e60b..d9b7e6b02c 100644 --- a/include/wx/qt/frame.h +++ b/include/wx/qt/frame.h @@ -13,7 +13,7 @@ #include "wx/frame.h" class QMainWindow; -class QScrollArea; +class QAbstractScrollArea; class WXDLLIMPEXP_CORE wxFrame : public wxFrameBase { @@ -51,7 +51,7 @@ public: virtual void RemoveChild( wxWindowBase *child ) override; QMainWindow *GetQMainWindow() const; - virtual QScrollArea *QtGetScrollBarsContainer() const override; + virtual QAbstractScrollArea *QtGetScrollBarsContainer() const override; protected: virtual wxPoint GetClientAreaOrigin() const override; diff --git a/include/wx/qt/listbox.h b/include/wx/qt/listbox.h index a8b072d568..4a123d712c 100644 --- a/include/wx/qt/listbox.h +++ b/include/wx/qt/listbox.h @@ -10,7 +10,7 @@ class QListWidget; class QModelIndex; -class QScrollArea; +class QAbstractScrollArea; class WXDLLIMPEXP_CORE wxListBox : public wxListBoxBase { @@ -87,7 +87,7 @@ protected: virtual int DoListHitTest(const wxPoint& point) const override; - virtual QScrollArea *QtGetScrollBarsContainer() const override; + virtual QAbstractScrollArea *QtGetScrollBarsContainer() const override; #if wxUSE_CHECKLISTBOX bool m_hasCheckBoxes; diff --git a/include/wx/qt/textctrl.h b/include/wx/qt/textctrl.h index 7b24c03773..741f90122e 100644 --- a/include/wx/qt/textctrl.h +++ b/include/wx/qt/textctrl.h @@ -8,7 +8,7 @@ #ifndef _WX_QT_TEXTCTRL_H_ #define _WX_QT_TEXTCTRL_H_ -class QScrollArea; +class QAbstractScrollArea; class wxQtEdit; class WXDLLIMPEXP_CORE wxTextCtrl : public wxTextCtrlBase @@ -93,7 +93,7 @@ protected: virtual bool DoLoadFile(const wxString& file, int fileType) override; virtual bool DoSaveFile(const wxString& file, int fileType) override; - virtual QScrollArea *QtGetScrollBarsContainer() const override; + virtual QAbstractScrollArea *QtGetScrollBarsContainer() const override; // From wxTextEntry: virtual wxWindow *GetEditableWindow() override { return this; } diff --git a/include/wx/qt/window.h b/include/wx/qt/window.h index 27eb929b00..62ac510cd0 100644 --- a/include/wx/qt/window.h +++ b/include/wx/qt/window.h @@ -15,7 +15,7 @@ class QShortcut; template < class T > class QList; class QWidget; -class QScrollArea; +class QAbstractScrollArea; class QScrollBar; class QPicture; class QPainter; @@ -181,7 +181,7 @@ public: virtual void QtHandleShortcut ( int command ); #endif // wxUSE_ACCEL - virtual QScrollArea *QtGetScrollBarsContainer() const; + virtual QAbstractScrollArea *QtGetScrollBarsContainer() const; #if wxUSE_TOOLTIPS // applies tooltip to the widget. @@ -232,7 +232,7 @@ protected: private: void Init(); - QScrollArea *m_qtContainer; // either nullptr or the same as m_qtWindow pointer + QAbstractScrollArea *m_qtContainer; // either nullptr or the same as m_qtWindow pointer // Return the viewport of m_qtContainer, if it's used, or just m_qtWindow. // diff --git a/src/qt/dcclient.cpp b/src/qt/dcclient.cpp index 5327ccfccc..4bd150c0ef 100644 --- a/src/qt/dcclient.cpp +++ b/src/qt/dcclient.cpp @@ -10,6 +10,7 @@ #include +#include #ifndef WX_PRECOMP #include "wx/log.h" @@ -20,7 +21,6 @@ #include "wx/qt/dcclient.h" #include "wx/qt/private/converter.h" -#include #include //############################################################################## diff --git a/src/qt/frame.cpp b/src/qt/frame.cpp index f47a4bab03..6d94f5670e 100644 --- a/src/qt/frame.cpp +++ b/src/qt/frame.cpp @@ -19,7 +19,6 @@ #include "wx/qt/private/converter.h" #include "wx/qt/private/winevent.h" -#include #include #include @@ -210,7 +209,7 @@ void wxFrame::RemoveChild( wxWindowBase *child ) wxFrameBase::RemoveChild( child ); } -QScrollArea *wxFrame::QtGetScrollBarsContainer() const +QAbstractScrollArea *wxFrame::QtGetScrollBarsContainer() const { return nullptr; } diff --git a/src/qt/listbox.cpp b/src/qt/listbox.cpp index b34c62fb3d..324ae12d6d 100644 --- a/src/qt/listbox.cpp +++ b/src/qt/listbox.cpp @@ -368,9 +368,9 @@ void wxListBox::QtSendEvent(wxEventType evtType, int rowIndex, bool selected) SendEvent(evtType, rowIndex, selected); } -QScrollArea *wxListBox::QtGetScrollBarsContainer() const +QAbstractScrollArea *wxListBox::QtGetScrollBarsContainer() const { - return (QScrollArea *) m_qtListWidget; + return static_cast(m_qtListWidget); } void wxListBox::UnSelectAll() diff --git a/src/qt/textctrl.cpp b/src/qt/textctrl.cpp index c1e59da2b5..6ed0428e3d 100644 --- a/src/qt/textctrl.cpp +++ b/src/qt/textctrl.cpp @@ -44,7 +44,7 @@ public: virtual long XYToPosition(long x, long y) const = 0; virtual bool PositionToXY(long pos, long *x, long *y) const = 0; virtual wxTextCtrlHitTestResult HitTest(const wxPoint& pt, long *pos) const = 0; - virtual QScrollArea *ScrollBarsContainer() const = 0; + virtual QAbstractScrollArea *ScrollBarsContainer() const = 0; virtual void WriteText( const wxString &text ) = 0; virtual void SetMaxLength(unsigned long len) = 0; virtual void MarkDirty() = 0; @@ -353,9 +353,9 @@ public: m_edit->ensureCursorVisible(); } - QScrollArea *ScrollBarsContainer() const override + QAbstractScrollArea *ScrollBarsContainer() const override { - return (QScrollArea *) m_edit; + return static_cast(m_edit); } virtual void SetStyleFlags(long flags) override @@ -559,7 +559,7 @@ public: return wxTE_HT_ON_TEXT; } - virtual QScrollArea *ScrollBarsContainer() const override + virtual QAbstractScrollArea *ScrollBarsContainer() const override { return nullptr; } @@ -911,7 +911,7 @@ QWidget *wxTextCtrl::GetHandle() const return (QWidget *) m_qtEdit->GetHandle(); } -QScrollArea *wxTextCtrl::QtGetScrollBarsContainer() const +QAbstractScrollArea *wxTextCtrl::QtGetScrollBarsContainer() const { return m_qtEdit->ScrollBarsContainer(); } diff --git a/src/qt/window.cpp b/src/qt/window.cpp index 1f4f008610..549db5d0e5 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -701,7 +701,7 @@ QWidget *wxWindowQt::QtGetClientWidget() const /* Returns a scrollbar for the given orientation */ QScrollBar *wxWindowQt::QtGetScrollBar( int orientation ) const { - QScrollArea *scrollArea = QtGetScrollBarsContainer(); + QAbstractScrollArea *scrollArea = QtGetScrollBarsContainer(); wxCHECK_MSG( scrollArea, nullptr, "Window without scrolling area" ); if ( orientation == wxHORIZONTAL ) @@ -1774,7 +1774,7 @@ QWidget *wxWindowQt::GetHandle() const return m_qtWindow; } -QScrollArea *wxWindowQt::QtGetScrollBarsContainer() const +QAbstractScrollArea *wxWindowQt::QtGetScrollBarsContainer() const { return m_qtContainer; } From 31aac5fac445310c2975eec4220f95ec0f9343bf Mon Sep 17 00:00:00 2001 From: ali kettab Date: Fri, 15 Dec 2023 20:49:02 +0100 Subject: [PATCH 128/257] Get rid of QtGetScrollBarsContainer() from wxWindow API under wxQt Because It is simpler to initialize (the inherited) m_qtContainer member directly in derived classes during construction process, and make the API a little bit cleaner. --- include/wx/qt/frame.h | 1 - include/wx/qt/listbox.h | 2 -- include/wx/qt/textctrl.h | 2 -- include/wx/qt/window.h | 8 ++++---- src/qt/frame.cpp | 5 ----- src/qt/listbox.cpp | 6 +----- src/qt/textctrl.cpp | 8 +++----- src/qt/window.cpp | 40 +++++++++++++++++----------------------- 8 files changed, 25 insertions(+), 47 deletions(-) diff --git a/include/wx/qt/frame.h b/include/wx/qt/frame.h index d9b7e6b02c..b538df7ddb 100644 --- a/include/wx/qt/frame.h +++ b/include/wx/qt/frame.h @@ -51,7 +51,6 @@ public: virtual void RemoveChild( wxWindowBase *child ) override; QMainWindow *GetQMainWindow() const; - virtual QAbstractScrollArea *QtGetScrollBarsContainer() const override; protected: virtual wxPoint GetClientAreaOrigin() const override; diff --git a/include/wx/qt/listbox.h b/include/wx/qt/listbox.h index 4a123d712c..6607c95bd1 100644 --- a/include/wx/qt/listbox.h +++ b/include/wx/qt/listbox.h @@ -87,8 +87,6 @@ protected: virtual int DoListHitTest(const wxPoint& point) const override; - virtual QAbstractScrollArea *QtGetScrollBarsContainer() const override; - #if wxUSE_CHECKLISTBOX bool m_hasCheckBoxes; #endif // wxUSE_CHECKLISTBOX diff --git a/include/wx/qt/textctrl.h b/include/wx/qt/textctrl.h index 741f90122e..389421b02e 100644 --- a/include/wx/qt/textctrl.h +++ b/include/wx/qt/textctrl.h @@ -93,8 +93,6 @@ protected: virtual bool DoLoadFile(const wxString& file, int fileType) override; virtual bool DoSaveFile(const wxString& file, int fileType) override; - virtual QAbstractScrollArea *QtGetScrollBarsContainer() const override; - // From wxTextEntry: virtual wxWindow *GetEditableWindow() override { return this; } diff --git a/include/wx/qt/window.h b/include/wx/qt/window.h index 62ac510cd0..b631e7172c 100644 --- a/include/wx/qt/window.h +++ b/include/wx/qt/window.h @@ -181,8 +181,6 @@ public: virtual void QtHandleShortcut ( int command ); #endif // wxUSE_ACCEL - virtual QAbstractScrollArea *QtGetScrollBarsContainer() const; - #if wxUSE_TOOLTIPS // applies tooltip to the widget. virtual void QtApplyToolTip(const wxString& text); @@ -228,11 +226,13 @@ protected: // itself. virtual QWidget* QtGetParentWidget() const { return GetHandle(); } - QWidget *m_qtWindow; + QWidget *m_qtWindow; + QAbstractScrollArea *m_qtContainer; // either nullptr or the same as m_qtWindow pointer + // if m_qtWindow derives from QAbstractScrollArea, + // e.g. QListWidget and QTextEdit. private: void Init(); - QAbstractScrollArea *m_qtContainer; // either nullptr or the same as m_qtWindow pointer // Return the viewport of m_qtContainer, if it's used, or just m_qtWindow. // diff --git a/src/qt/frame.cpp b/src/qt/frame.cpp index 6d94f5670e..04688697f9 100644 --- a/src/qt/frame.cpp +++ b/src/qt/frame.cpp @@ -209,11 +209,6 @@ void wxFrame::RemoveChild( wxWindowBase *child ) wxFrameBase::RemoveChild( child ); } -QAbstractScrollArea *wxFrame::QtGetScrollBarsContainer() const -{ - return nullptr; -} - // get the origin of the client area in the client coordinates // excluding any menubar and toolbar if any. wxPoint wxFrame::GetClientAreaOrigin() const diff --git a/src/qt/listbox.cpp b/src/qt/listbox.cpp index 324ae12d6d..4ec9f37936 100644 --- a/src/qt/listbox.cpp +++ b/src/qt/listbox.cpp @@ -178,6 +178,7 @@ void wxListBox::DoCreate(wxWindow* parent, long style) Init(); m_qtWindow = + m_qtContainer = m_qtListWidget = new wxQtListWidget( parent, this ); if ( style & wxLB_SORT ) @@ -368,11 +369,6 @@ void wxListBox::QtSendEvent(wxEventType evtType, int rowIndex, bool selected) SendEvent(evtType, rowIndex, selected); } -QAbstractScrollArea *wxListBox::QtGetScrollBarsContainer() const -{ - return static_cast(m_qtListWidget); -} - void wxListBox::UnSelectAll() { Q_FOREACH(QListWidgetItem* l, m_qtListWidget->selectedItems()) diff --git a/src/qt/textctrl.cpp b/src/qt/textctrl.cpp index 6ed0428e3d..45ce4d4509 100644 --- a/src/qt/textctrl.cpp +++ b/src/qt/textctrl.cpp @@ -676,6 +676,9 @@ bool wxTextCtrl::Create(wxWindow *parent, m_qtEdit->SetStyleFlags(style); + m_qtWindow = + m_qtContainer = m_qtEdit->ScrollBarsContainer(); + if ( QtCreateControl( parent, id, pos, size, style, validator, name ) ) { // set the initial text value without sending the event: @@ -910,8 +913,3 @@ QWidget *wxTextCtrl::GetHandle() const { return (QWidget *) m_qtEdit->GetHandle(); } - -QAbstractScrollArea *wxTextCtrl::QtGetScrollBarsContainer() const -{ - return m_qtEdit->ScrollBarsContainer(); -} diff --git a/src/qt/window.cpp b/src/qt/window.cpp index 549db5d0e5..f13027b9a2 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -443,8 +443,8 @@ void wxWindowQt::AddChild( wxWindowBase *child ) { // Make sure all children are children of the inner scroll area widget (if any): - if ( QtGetScrollBarsContainer() ) - QtReparent( child->GetHandle(), QtGetScrollBarsContainer()->viewport() ); + if ( m_qtContainer ) + QtReparent( child->GetHandle(), m_qtContainer->viewport() ); wxWindowBase::AddChild( child ); } @@ -548,9 +548,9 @@ void wxWindowQt::Update() { wxLogTrace(TRACE_QT_WINDOW, wxT("wxWindow::Update %s"), GetName()); // send the paint event to the inner widget in scroll areas: - if ( QtGetScrollBarsContainer() ) + if ( m_qtContainer ) { - QtGetScrollBarsContainer()->viewport()->repaint(); + m_qtContainer->viewport()->repaint(); } else { GetHandle()->repaint(); } @@ -561,9 +561,9 @@ void wxWindowQt::Refresh( bool WXUNUSED( eraseBackground ), const wxRect *rect ) QWidget *widget; // get the inner widget in scroll areas: - if ( QtGetScrollBarsContainer() ) + if ( m_qtContainer ) { - widget = QtGetScrollBarsContainer()->viewport(); + widget = m_qtContainer->viewport(); } else { widget = GetHandle(); } @@ -701,15 +701,14 @@ QWidget *wxWindowQt::QtGetClientWidget() const /* Returns a scrollbar for the given orientation */ QScrollBar *wxWindowQt::QtGetScrollBar( int orientation ) const { - QAbstractScrollArea *scrollArea = QtGetScrollBarsContainer(); - wxCHECK_MSG( scrollArea, nullptr, "Window without scrolling area" ); + wxCHECK_MSG( m_qtContainer, nullptr, "Window without scrolling area" ); if ( orientation == wxHORIZONTAL ) { - return scrollArea->horizontalScrollBar(); + return m_qtContainer->horizontalScrollBar(); } - return scrollArea->verticalScrollBar(); + return m_qtContainer->verticalScrollBar(); } @@ -780,8 +779,8 @@ void wxWindowQt::ScrollWindow( int dx, int dy, const wxRect *rect ) { // check if this is a scroll area (scroll only inner viewport) QWidget *widget; - if ( QtGetScrollBarsContainer() ) - widget = QtGetScrollBarsContainer()->viewport(); + if ( m_qtContainer ) + widget = m_qtContainer->viewport(); else widget = GetHandle(); // scroll the widget or the specified rect (not children) @@ -1166,8 +1165,8 @@ bool wxWindowQt::QtSetBackgroundStyle() { QWidget *widget; // if it is a scroll area, don't make transparent (invisible) scroll bars: - if ( QtGetScrollBarsContainer() ) - widget = QtGetScrollBarsContainer()->viewport(); + if ( m_qtContainer ) + widget = m_qtContainer->viewport(); else widget = GetHandle(); // check if the control is created (wxGTK requires calling it before): @@ -1283,8 +1282,8 @@ bool wxWindowQt::QtHandlePaintEvent ( QWidget *handler, QPaintEvent *event ) * for the client area (the scrolled part). Events for the whole window * (including scrollbars and maybe status or menu bars are handled by Qt */ - if ( (QtGetScrollBarsContainer() && - QtGetScrollBarsContainer() != handler) || handler != GetHandle() ) + if ( (m_qtContainer && + m_qtContainer != handler) || handler != GetHandle() ) { return false; } @@ -1294,10 +1293,10 @@ bool wxWindowQt::QtHandlePaintEvent ( QWidget *handler, QPaintEvent *event ) // Prepare the Qt painter for wxWindowDC: bool ok = false; - if ( QtGetScrollBarsContainer() ) + if ( m_qtContainer ) { // QScrollArea can only draw in the viewport: - ok = m_qtPainter->begin( QtGetScrollBarsContainer()->viewport() ); + ok = m_qtPainter->begin( m_qtContainer->viewport() ); } if ( !ok ) { @@ -1774,11 +1773,6 @@ QWidget *wxWindowQt::GetHandle() const return m_qtWindow; } -QAbstractScrollArea *wxWindowQt::QtGetScrollBarsContainer() const -{ - return m_qtContainer; -} - void wxWindowQt::QtSetPicture( QPicture* pict ) { m_qtPicture.reset(pict); From ee009a6416ba832963055863d707fd5b8fa202b0 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Sun, 17 Dec 2023 12:36:47 +0100 Subject: [PATCH 129/257] Honor wxALWAYS_SHOW_SB flag if specified under wxQt --- src/qt/window.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/qt/window.cpp b/src/qt/window.cpp index f13027b9a2..7e52c15ba6 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -355,13 +355,25 @@ bool wxWindowQt::Create( wxWindowQt * parent, wxWindowID id, const wxPoint & pos { if ( style & (wxHSCROLL | wxVSCROLL) ) { + m_qtWindow = m_qtContainer = new wxQtScrollArea( parent, this ); - m_qtWindow = m_qtContainer; - // Create the scroll bars if needed: - if ( !(style & wxHSCROLL) ) - m_qtContainer->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); - if ( !(style & wxVSCROLL) ) - m_qtContainer->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); + + // If wx[HV]SCROLL is not given, the corresponding scrollbar is not shown + // at all. Otherwise it may be shown only on demand (default) or always, if + // the wxALWAYS_SHOW_SB is specified. + Qt::ScrollBarPolicy horzPolicy = (style & wxHSCROLL) + ? HasFlag(wxALWAYS_SHOW_SB) + ? Qt::ScrollBarAlwaysOn + : Qt::ScrollBarAsNeeded + : Qt::ScrollBarAlwaysOff; + Qt::ScrollBarPolicy vertPolicy = (style & wxVSCROLL) + ? HasFlag(wxALWAYS_SHOW_SB) + ? Qt::ScrollBarAlwaysOn + : Qt::ScrollBarAsNeeded + : Qt::ScrollBarAlwaysOff; + + m_qtContainer->setHorizontalScrollBarPolicy( horzPolicy ); + m_qtContainer->setVerticalScrollBarPolicy( vertPolicy ); } else m_qtWindow = new wxQtWidget( parent, this ); From 15f3f4c3af98407700d44773472b3ec35340e52f Mon Sep 17 00:00:00 2001 From: ali kettab Date: Sun, 17 Dec 2023 14:05:17 +0100 Subject: [PATCH 130/257] Refactor the code that chooses which widget to use for drawing under wxQt No real changes. --- src/qt/window.cpp | 79 +++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 50 deletions(-) diff --git a/src/qt/window.cpp b/src/qt/window.cpp index 7e52c15ba6..c21440f87e 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -38,6 +38,18 @@ #define TRACE_QT_WINDOW "qtwindow" +namespace +{ +inline QWidget* wxQtGetDrawingWidget(QAbstractScrollArea* qtContainer, + QWidget* qtWidget) +{ + if ( qtContainer && qtContainer->viewport() ) + return qtContainer->viewport(); + + return qtWidget; +} +} + // Base Widget helper (no scrollbar, used by wxWindow) class wxQtWidget : public wxQtEventSignalHandler< QWidget, wxWindowQt > @@ -560,25 +572,15 @@ void wxWindowQt::Update() { wxLogTrace(TRACE_QT_WINDOW, wxT("wxWindow::Update %s"), GetName()); // send the paint event to the inner widget in scroll areas: - if ( m_qtContainer ) - { - m_qtContainer->viewport()->repaint(); - } else { - GetHandle()->repaint(); - } + + QWidget* const widget = wxQtGetDrawingWidget(m_qtContainer, GetHandle()); + + widget->repaint(); } void wxWindowQt::Refresh( bool WXUNUSED( eraseBackground ), const wxRect *rect ) { - QWidget *widget; - - // get the inner widget in scroll areas: - if ( m_qtContainer ) - { - widget = m_qtContainer->viewport(); - } else { - widget = GetHandle(); - } + QWidget* const widget = wxQtGetDrawingWidget(m_qtContainer, GetHandle()); if ( widget != nullptr ) { @@ -695,19 +697,7 @@ void wxWindowQt::DoGetTextExtent(const wxString& string, int *x, int *y, int *de QWidget *wxWindowQt::QtGetClientWidget() const { - QWidget *qtWidget = nullptr; - if ( m_qtContainer != nullptr ) - { - qtWidget = m_qtContainer->viewport(); - } - - if ( qtWidget == nullptr ) - { - // We don't have scrollbars or the QScrollArea has no children - qtWidget = GetHandle(); - } - - return qtWidget; + return wxQtGetDrawingWidget(m_qtContainer, GetHandle()); } /* Returns a scrollbar for the given orientation */ @@ -790,11 +780,8 @@ int wxWindowQt::GetScrollRange( int orientation ) const void wxWindowQt::ScrollWindow( int dx, int dy, const wxRect *rect ) { // check if this is a scroll area (scroll only inner viewport) - QWidget *widget; - if ( m_qtContainer ) - widget = m_qtContainer->viewport(); - else - widget = GetHandle(); + QWidget* const widget = wxQtGetDrawingWidget(m_qtContainer, GetHandle()); + // scroll the widget or the specified rect (not children) if ( rect != nullptr ) widget->scroll( dx, dy, wxQtConvertRect( *rect )); @@ -1175,12 +1162,9 @@ bool wxWindowQt::SetBackgroundStyle(wxBackgroundStyle style) bool wxWindowQt::QtSetBackgroundStyle() { - QWidget *widget; // if it is a scroll area, don't make transparent (invisible) scroll bars: - if ( m_qtContainer ) - widget = m_qtContainer->viewport(); - else - widget = GetHandle(); + QWidget* const widget = wxQtGetDrawingWidget(m_qtContainer, GetHandle()); + // check if the control is created (wxGTK requires calling it before): if ( widget != nullptr ) { @@ -1303,18 +1287,13 @@ bool wxWindowQt::QtHandlePaintEvent ( QWidget *handler, QPaintEvent *event ) // use the Qt event region: m_updateRegion.QtSetRegion( event->region() ); - // Prepare the Qt painter for wxWindowDC: - bool ok = false; - if ( m_qtContainer ) - { - // QScrollArea can only draw in the viewport: - ok = m_qtPainter->begin( m_qtContainer->viewport() ); - } - if ( !ok ) - { - // Start the paint in the widget itself - ok = m_qtPainter->begin( GetHandle() ); - } + // Prepare the Qt painter: + QWidget* const widget = wxQtGetDrawingWidget(m_qtContainer, GetHandle()); + + // Start the paint in the viewport if _widget_ is a scroll area, because + // QAbstractScrollArea can only draw in it. Start the paint in the widget + // itself otherwise. + const bool ok = m_qtPainter->begin( widget ); if ( ok ) { From 840d362a707c62b46f1e06386b08058bf35200e3 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Sun, 17 Dec 2023 15:06:39 +0100 Subject: [PATCH 131/257] Keep forward declarations of Qt classes in alphabetical order --- include/wx/qt/window.h | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/include/wx/qt/window.h b/include/wx/qt/window.h index b631e7172c..b7d806976b 100644 --- a/include/wx/qt/window.h +++ b/include/wx/qt/window.h @@ -14,26 +14,23 @@ class QShortcut; template < class T > class QList; -class QWidget; class QAbstractScrollArea; -class QScrollBar; -class QPicture; class QPainter; +class QPicture; +class QScrollBar; +class QWidget; +class QCloseEvent; +class QContextMenuEvent; +class QEvent; +class QFocusEvent; +class QKeyEvent; class QPaintEvent; class QResizeEvent; class QWheelEvent; -class QKeyEvent; class QMouseEvent; -class QEvent; class QMoveEvent; -class QEvent; -class QEvent; -class QCloseEvent; -class QContextMenuEvent; -class QFocusEvent; -class WXDLLIMPEXP_FWD_CORE wxScrollBar; class WXDLLIMPEXP_FWD_CORE wxQtShortcutHandler; /* wxQt specific notes: From 69ec562f16bff97dec32321918b81739f26fc283 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Sun, 17 Dec 2023 15:13:31 +0100 Subject: [PATCH 132/257] Update outdated comments under wxQt There is no longer a QtGetContainer() function name. wxQtEventForwarder was renamed to wxQtEventSignalHandler. And QtGetScrollBarContainer() was just removed in previous commits. --- include/wx/qt/private/winevent.h | 2 +- include/wx/qt/window.h | 18 ++++++------------ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/include/wx/qt/private/winevent.h b/include/wx/qt/private/winevent.h index 79734ded16..fb1fc431e1 100644 --- a/include/wx/qt/private/winevent.h +++ b/include/wx/qt/private/winevent.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: include/wx/qt/winevent_qt.h +// Name: include/wx/qt/private/winevent.h // Purpose: QWidget to wxWindow event handler // Author: Javier Torres, Peter Most // Created: 21.06.10 diff --git a/include/wx/qt/window.h b/include/wx/qt/window.h index b7d806976b..2fb91ee162 100644 --- a/include/wx/qt/window.h +++ b/include/wx/qt/window.h @@ -37,20 +37,14 @@ class WXDLLIMPEXP_FWD_CORE wxQtShortcutHandler; * * Remember to implement the Qt object getters on all subclasses: * - GetHandle() returns the Qt object - * - QtGetScrollBarsContainer() returns the widget where scrollbars are placed - * For example, for wxFrame, GetHandle() is the QMainWindow, - * QtGetScrollBarsContainer() is the central widget and QtGetContainer() is a widget - * in a layout inside the central widget that also contains the scrollbars. - * Return 0 from QtGetScrollBarsContainer() to disable SetScrollBar() and friends - * for wxWindow subclasses. * * - * Event handling is achieved by using the template class wxQtEventForwarder - * found in winevent_qt.(h|cpp) to send all Qt events here to QtHandleXXXEvent() - * methods. All these methods receive the Qt event and the handler. This is - * done because events of the containers (the scrolled part of the window) are - * sent to the same wxWindow instance, that must be able to differentiate them - * as some events need different handling (paintEvent) depending on that. + * Event handling is achieved by using the template class wxQtEventSignalHandler + * found in winevent.h to send all Qt events here to QtHandleXXXEvent() methods. + * All these methods receive the Qt event and the handler. This is done because + * events of the containers (the scrolled part of the window) are sent to the + * same wxWindow instance, that must be able to differentiate them as some events + * need different handling (paintEvent) depending on that. * We pass the QWidget pointer to all event handlers for consistency. */ class WXDLLIMPEXP_CORE wxWindowQt : public wxWindowBase From 62d652c353f0bb01a43117b102f493b310abe357 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Dec 2023 16:31:24 +0100 Subject: [PATCH 133/257] Use wxUSE_AUI_LIVE_RESIZE_ALWAYS instead of explicit port checks This allows to avoid repeating the checks for the ports in which wxClientDC can't be used in multiple places. No real changes. --- src/aui/framemanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index aa2e448e9f..26cbb7da3a 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -3911,7 +3911,7 @@ void wxAuiManager::Render(wxDC* dc) void wxAuiManager::Repaint(wxDC* dc) { -#if defined(__WXMAC__) || defined(__WXGTK3__) +#if wxUSE_AUI_LIVE_RESIZE_ALWAYS // We can't use wxClientDC in these ports. if ( dc == nullptr ) { From f82047feafebd2124ed8540f44b9bd6c3f28076d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Dec 2023 16:39:16 +0100 Subject: [PATCH 134/257] Make wxAuiManager::Repaint() logic a bit more clear No real changes, just write a single check for "dc == nullptr" instead of doing it twice in combination with preprocessor checks. This commit is best viewed with Git --color-moved option. --- src/aui/framemanager.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 26cbb7da3a..ac00f3053d 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -3911,28 +3911,27 @@ void wxAuiManager::Render(wxDC* dc) void wxAuiManager::Repaint(wxDC* dc) { -#if wxUSE_AUI_LIVE_RESIZE_ALWAYS - // We can't use wxClientDC in these ports. - if ( dc == nullptr ) - { - m_frame->Refresh() ; - m_frame->Update() ; - return ; - } -#endif - int w, h; - m_frame->GetClientSize(&w, &h); + wxClientDC* client_dc = nullptr; // figure out which dc to use; if one // has been specified, use it, otherwise // make a client dc - wxClientDC* client_dc = nullptr; if (!dc) { +#if wxUSE_AUI_LIVE_RESIZE_ALWAYS + // We can't use wxClientDC in these ports. + m_frame->Refresh() ; + m_frame->Update() ; + return ; +#else client_dc = new wxClientDC(m_frame); dc = client_dc; +#endif } + int w, h; + m_frame->GetClientSize(&w, &h); + // if the frame has a toolbar, the client area // origin will not be (0,0). wxPoint pt = m_frame->GetClientAreaOrigin(); From aa14096ca98365e77b5906373497ea5718d3a802 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Dec 2023 16:42:14 +0100 Subject: [PATCH 135/257] Use unique_ptr instead of manual memory management No real changes, just use unique_ptr instead of deleting the DC object manually. --- src/aui/framemanager.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index ac00f3053d..43f24e2933 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -64,6 +64,8 @@ wxDEFINE_EVENT( wxEVT_AUI_FIND_MANAGER, wxAuiManagerEvent ); #include "wx/msw/dc.h" #endif +#include + wxIMPLEMENT_DYNAMIC_CLASS(wxAuiManagerEvent, wxEvent); wxIMPLEMENT_CLASS(wxAuiManager, wxEvtHandler); @@ -3911,7 +3913,7 @@ void wxAuiManager::Render(wxDC* dc) void wxAuiManager::Repaint(wxDC* dc) { - wxClientDC* client_dc = nullptr; + std::unique_ptr client_dc; // figure out which dc to use; if one // has been specified, use it, otherwise @@ -3924,8 +3926,8 @@ void wxAuiManager::Repaint(wxDC* dc) m_frame->Update() ; return ; #else - client_dc = new wxClientDC(m_frame); - dc = client_dc; + client_dc.reset(new wxClientDC(m_frame)); + dc = client_dc.get(); #endif } @@ -3940,10 +3942,6 @@ void wxAuiManager::Repaint(wxDC* dc) // render all the items Render(dc); - - // if we created a client_dc, delete it - if (client_dc) - delete client_dc; } void wxAuiManager::OnDestroy(wxWindowDestroyEvent& event) From 24fd54ed31a8b09dade9d6124d88042cd322a08b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Dec 2023 18:31:36 +0100 Subject: [PATCH 136/257] Add wxClientDC::CanBeUsedForDrawing() This function can be used to check if drawing on wxClientDC actually works. This has to be a run-time, rather than compile-time, check because in wxGTK3 this depends on the backend being used: wxClientDC only doesn't work with Wayland, but does work with X11 (and, less importantly, Win32) backend(s). Currently the wxWindow parameter of this function is not used but it could be useful in the future and it will be simpler to allow not specifying it (by defaulting it to nullptr) than to add it later, so it seems better to have it. --- include/wx/dc.h | 4 ++++ include/wx/dcclient.h | 2 ++ include/wx/dfb/dcclient.h | 3 +++ include/wx/gtk/dc.h | 2 ++ include/wx/gtk/dcclient.h | 3 +++ include/wx/msw/dcclient.h | 3 +++ include/wx/osx/dcclient.h | 3 +++ include/wx/qt/dcclient.h | 3 +++ include/wx/x11/dcclient.h | 3 +++ interface/wx/dcclient.h | 30 ++++++++++++++++++++++++------ src/common/dcbase.cpp | 11 +++++++++++ src/gtk/dc.cpp | 19 +++++++++++++++++++ 12 files changed, 80 insertions(+), 6 deletions(-) diff --git a/include/wx/dc.h b/include/wx/dc.h index 26402a5859..b89c38130f 100644 --- a/include/wx/dc.h +++ b/include/wx/dc.h @@ -128,6 +128,8 @@ public: virtual wxDCImpl* CreatePrinterDC( wxPrinterDC *owner, const wxPrintData &data ) = 0; #endif + virtual bool CanDrawUsingClientDC(const wxWindow* window) const = 0; + static void Set(wxDCFactory *factory); static wxDCFactory *Get(); @@ -154,6 +156,8 @@ public: #if wxUSE_PRINTING_ARCHITECTURE virtual wxDCImpl* CreatePrinterDC( wxPrinterDC *owner, const wxPrintData &data ) override; #endif + + virtual bool CanDrawUsingClientDC(const wxWindow* window) const override; }; //----------------------------------------------------------------------------- diff --git a/include/wx/dcclient.h b/include/wx/dcclient.h index 28391d1266..ced769ce34 100644 --- a/include/wx/dcclient.h +++ b/include/wx/dcclient.h @@ -36,6 +36,8 @@ class WXDLLIMPEXP_CORE wxClientDC : public wxWindowDC public: wxClientDC(wxWindow *win); + static bool CanBeUsedForDrawing(const wxWindow* window); + protected: wxClientDC(wxDCImpl *impl) : wxWindowDC(impl) { } diff --git a/include/wx/dfb/dcclient.h b/include/wx/dfb/dcclient.h index 98655e4fd3..f195829f14 100644 --- a/include/wx/dfb/dcclient.h +++ b/include/wx/dfb/dcclient.h @@ -51,6 +51,9 @@ public: wxClientDCImpl(wxDC *owner) : wxWindowDCImpl(owner) { } wxClientDCImpl(wxDC *owner, wxWindow *win); + static bool + CanBeUsedForDrawing(const wxWindow* WXUNUSED(window)) { return true; } + wxDECLARE_DYNAMIC_CLASS(wxClientDCImpl); wxDECLARE_NO_COPY_CLASS(wxClientDCImpl); }; diff --git a/include/wx/gtk/dc.h b/include/wx/gtk/dc.h index 472c90fe11..dd9baf9725 100644 --- a/include/wx/gtk/dc.h +++ b/include/wx/gtk/dc.h @@ -64,6 +64,8 @@ class wxClientDCImpl: public wxGTKCairoDCImpl public: wxClientDCImpl(wxClientDC* owner, wxWindow* window); + static bool CanBeUsedForDrawing(const wxWindow* window); + wxDECLARE_NO_COPY_CLASS(wxClientDCImpl); }; //----------------------------------------------------------------------------- diff --git a/include/wx/gtk/dcclient.h b/include/wx/gtk/dcclient.h index 6b42e90467..f6d6f3ed5d 100644 --- a/include/wx/gtk/dcclient.h +++ b/include/wx/gtk/dcclient.h @@ -150,6 +150,9 @@ public: virtual void DoGetSize(int *width, int *height) const override; + static bool + CanBeUsedForDrawing(const wxWindow* WXUNUSED(window)) { return true; } + wxDECLARE_ABSTRACT_CLASS(wxClientDCImpl); }; diff --git a/include/wx/msw/dcclient.h b/include/wx/msw/dcclient.h index d6eaffda58..01f2cca210 100644 --- a/include/wx/msw/dcclient.h +++ b/include/wx/msw/dcclient.h @@ -56,6 +56,9 @@ public: virtual void DoGetSize(int *width, int *height) const override; + static bool + CanBeUsedForDrawing(const wxWindow* WXUNUSED(window)) { return true; } + protected: void InitDC(); diff --git a/include/wx/osx/dcclient.h b/include/wx/osx/dcclient.h index d5840ad98a..be16886f1b 100644 --- a/include/wx/osx/dcclient.h +++ b/include/wx/osx/dcclient.h @@ -54,6 +54,9 @@ public: wxClientDCImpl( wxDC *owner, wxWindow *window ); virtual ~wxClientDCImpl(); + static bool + CanBeUsedForDrawing(const wxWindow* WXUNUSED(window)) { return false; } + private: wxDECLARE_CLASS(wxClientDCImpl); wxDECLARE_NO_COPY_CLASS(wxClientDCImpl); diff --git a/include/wx/qt/dcclient.h b/include/wx/qt/dcclient.h index 788c4867ba..3eafbed172 100644 --- a/include/wx/qt/dcclient.h +++ b/include/wx/qt/dcclient.h @@ -40,6 +40,9 @@ public: wxClientDCImpl( wxDC *owner ); wxClientDCImpl( wxDC *owner, wxWindow *win ); + static bool + CanBeUsedForDrawing(const wxWindow* WXUNUSED(window)) { return false; } + private: wxDECLARE_CLASS(wxClientDCImpl); wxDECLARE_NO_COPY_CLASS(wxClientDCImpl); diff --git a/include/wx/x11/dcclient.h b/include/wx/x11/dcclient.h index beca1247de..7c477ed34f 100644 --- a/include/wx/x11/dcclient.h +++ b/include/wx/x11/dcclient.h @@ -153,6 +153,9 @@ public: wxClientDCImpl( wxDC *owner ) : wxWindowDCImpl( owner ) { } wxClientDCImpl( wxDC *owner, wxWindow *win ); + static bool + CanBeUsedForDrawing(const wxWindow* WXUNUSED(window)) { return true; } + protected: virtual void DoGetSize(int *width, int *height) const; diff --git a/interface/wx/dcclient.h b/interface/wx/dcclient.h index 05058d016a..41997f18ed 100644 --- a/interface/wx/dcclient.h +++ b/interface/wx/dcclient.h @@ -63,12 +63,13 @@ public: window from outside an EVT_PAINT() handler in some ports, this does @em not work on most of the platforms: neither wxOSX nor wxGTK with GTK 3 Wayland backend support this at all, so drawing using wxClientDC simply doesn't - have any effect there, while wxMSW doesn't support using it for composited - windows, so wxWindow::MSWDisableComposited() must be called to allow it to - work. The only supported way of drawing on a window is via wxPaintDC. To - redraw a small part of the window, use wxWindow::RefreshRect() to - invalidate just this part and check wxWindow::GetUpdateRegion() in the - paint event handler to redraw this part only. + have any effect there. CanBeUsedForDrawing() can be used to determine + whether wxClientDC can be used for drawing in the current environment, but + it is recommended to only draw on the window using wxPaintDC, as this is + guaranteed to work everywhere. To redraw a small part of the window, use + wxWindow::RefreshRect() to invalidate just this part and check + wxWindow::GetUpdateRegion() in the paint event handler to redraw this part + only. wxClientDC objects should normally be constructed as temporary stack objects, i.e. don't store a wxClientDC object. @@ -88,6 +89,23 @@ public: Constructor. Pass a pointer to the window on which you wish to paint. */ wxClientDC(wxWindow* window); + + /** + Return true if drawing on wxClientDC actually works. + + In many environments (currently this includes wxGTK when using Wayland + backend, wxMSW when using double buffering and wxOSX in all cases), + wxClientDC can be only used for obtaining information about the device + context, but not for actually drawing on it. Portable code should avoid + using wxClientDC completely, as explained in the class documentation, + but it is also possible to optionally use it only when it does work, + i.e. when this function returns @true. + + @param window The window that would be used with wxClientDC. + + @since 3.3.0 + */ + static bool CanBeUsedForDrawing(const wxWindow* window); }; diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index e1060ae402..f36020179c 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -174,6 +174,11 @@ wxDCImpl *wxNativeDCFactory::CreatePrinterDC( wxPrinterDC *owner, const wxPrintD } #endif +bool wxNativeDCFactory::CanDrawUsingClientDC(const wxWindow* window) const +{ + return wxClientDCImpl::CanBeUsedForDrawing(window); +} + //----------------------------------------------------------------------------- // wxWindowDC //----------------------------------------------------------------------------- @@ -196,6 +201,12 @@ wxClientDC::wxClientDC(wxWindow *win) { } +/* static */ +bool wxClientDC::CanBeUsedForDrawing(const wxWindow* window) +{ + return wxDCFactory::Get()->CanDrawUsingClientDC(window); +} + //----------------------------------------------------------------------------- // wxMemoryDC //----------------------------------------------------------------------------- diff --git a/src/gtk/dc.cpp b/src/gtk/dc.cpp index 2c0e3d77c9..4cb49d135f 100644 --- a/src/gtk/dc.cpp +++ b/src/gtk/dc.cpp @@ -486,6 +486,25 @@ wxClientDCImpl::wxClientDCImpl(wxClientDC* owner, wxWindow* window) else SetGraphicsContext(wxGraphicsContext::Create()); } + +/* static */ +bool wxClientDCImpl::CanBeUsedForDrawing(const wxWindow* WXUNUSED(window)) +{ +#ifdef __UNIX__ + switch ( wxGetDisplayInfo().type ) + { + case wxDisplayNone: + case wxDisplayX11: + break; + + case wxDisplayWayland: + return false; + } +#endif // __UNIX__ + + return true; +} + //----------------------------------------------------------------------------- wxPaintDCImpl::wxPaintDCImpl(wxPaintDC* owner, wxWindow* window) From 298fef23adf018211258f2bc61ba10de2dee22f7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Dec 2023 18:38:08 +0100 Subject: [PATCH 137/257] Use wxClientDC::CanBeUsedForDrawing() in wxSplitterWindow No real changes, just simplify the code by using the just added wxClientDC function instead of reproducing its logic here. --- src/generic/splitter.cpp | 21 ++++----------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/src/generic/splitter.cpp b/src/generic/splitter.cpp index e457f5c6d4..ed0dc2710d 100644 --- a/src/generic/splitter.cpp +++ b/src/generic/splitter.cpp @@ -74,25 +74,12 @@ static bool IsLive(wxSplitterWindow* wnd) // with wxSP_LIVE_UPDATE style the splitter windows are always resized // following the mouse movement while it drags the sash, without it we only // draw the sash at the new position but only resize the windows when the - // dragging is finished -#if defined( __WXMAC__ ) && defined(TARGET_API_MAC_OSX) && TARGET_API_MAC_OSX == 1 - return true; // Mac can't paint outside paint event - always need live mode -#else - // wxClientDC doesn't work with Wayland either, so check if we're using it. - #if defined(__WXGTK3__) && defined(__UNIX__) - switch ( wxGetDisplayInfo().type ) - { - case wxDisplayNone: - case wxDisplayX11: - break; - - case wxDisplayWayland: - return true; - } - #endif // wxGTK3 + // dragging is finished -- but drawing the sash is done using wxClientDC, + // so check if we can use it and always use live resizing if we can't + if ( !wxClientDC::CanBeUsedForDrawing(wnd) ) + return true; return wnd->HasFlag(wxSP_LIVE_UPDATE); -#endif } bool wxSplitterWindow::Create(wxWindow *parent, wxWindowID id, From 1d328aa4e1928e1d199f0314b52cd6a2bb24509a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Dec 2023 18:51:42 +0100 Subject: [PATCH 138/257] Add wxSplitterWindow::AlwaysUsesLiveUpdate() This is similar to wxAuiManager::AlwaysUsesLiveResize() and does the same thing, i.e. returns true if live update is always used, whether wxSP_LIVE_UPDATE is enabled or not. Use the new function in the sample to disable the menu item in the environments where it doesn't do anything, as it was confusing to have it under e.g. Wayland. --- include/wx/generic/splitter.h | 3 +++ interface/wx/splitter.h | 14 ++++++++++++++ samples/splitter/splitter.cpp | 8 +++++++- src/generic/splitter.cpp | 10 ++++++---- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/include/wx/generic/splitter.h b/include/wx/generic/splitter.h index 2294f431e4..f2fbe2a906 100644 --- a/include/wx/generic/splitter.h +++ b/include/wx/generic/splitter.h @@ -131,6 +131,9 @@ public: // Is the window split? bool IsSplit() const { return (m_windowTwo != nullptr); } + // Return true if wxSP_LIVE_UPDATE is always used. + bool AlwaysUsesLiveUpdate() const; + // Sets the border size void SetBorderSize(int WXUNUSED(width)) { } diff --git a/interface/wx/splitter.h b/interface/wx/splitter.h index 4ff835b2ee..22d564a7ea 100644 --- a/interface/wx/splitter.h +++ b/interface/wx/splitter.h @@ -142,6 +142,20 @@ public: */ virtual ~wxSplitterWindow(); + /** + Returns true if splitter always behaves as if wxSP_LIVE_UPDATE were + specified. + + This function returns true if non-live update mode is not supported and + live update is always used, even if wxSP_LIVE_UPDATE was not explicitly + specified. + + @see wxClientDC::CanBeUsedForDrawing() + + @since 3.3.0 + */ + bool AlwaysUsesLiveUpdate() const; + /** Creation function, for two-step construction. See wxSplitterWindow() for details. diff --git a/samples/splitter/splitter.cpp b/samples/splitter/splitter.cpp index 3d100be780..cee9eafc03 100644 --- a/samples/splitter/splitter.cpp +++ b/samples/splitter/splitter.cpp @@ -254,7 +254,7 @@ MyFrame::MyFrame() "Toggle sash invisibility"); splitMenu->AppendSeparator(); - splitMenu->AppendCheckItem(SPLIT_LIVE, + auto itemLive = splitMenu->AppendCheckItem(SPLIT_LIVE, "&Live update\tCtrl-L", "Toggle live update mode"); splitMenu->AppendCheckItem(SPLIT_BORDER, @@ -306,6 +306,12 @@ MyFrame::MyFrame() menuBar->Check(SPLIT_LIVE, true); m_splitter = new MySplitterWindow(this); + if ( m_splitter->AlwaysUsesLiveUpdate() ) + { + // Only live update mode is supported, so this menu item can't be used. + itemLive->Enable(false); + } + // If you use non-zero gravity you must initialize the splitter with its // correct initial size, otherwise it will change the sash position by a // huge amount when it's resized from its initial default size to its real diff --git a/src/generic/splitter.cpp b/src/generic/splitter.cpp index ed0dc2710d..5636704951 100644 --- a/src/generic/splitter.cpp +++ b/src/generic/splitter.cpp @@ -69,6 +69,11 @@ wxBEGIN_EVENT_TABLE(wxSplitterWindow, wxWindow) #endif // wxMSW wxEND_EVENT_TABLE() +bool wxSplitterWindow::AlwaysUsesLiveUpdate() const +{ + return !wxClientDC::CanBeUsedForDrawing(this); +} + static bool IsLive(wxSplitterWindow* wnd) { // with wxSP_LIVE_UPDATE style the splitter windows are always resized @@ -76,10 +81,7 @@ static bool IsLive(wxSplitterWindow* wnd) // draw the sash at the new position but only resize the windows when the // dragging is finished -- but drawing the sash is done using wxClientDC, // so check if we can use it and always use live resizing if we can't - if ( !wxClientDC::CanBeUsedForDrawing(wnd) ) - return true; - - return wnd->HasFlag(wxSP_LIVE_UPDATE); + return wnd->AlwaysUsesLiveUpdate() || wnd->HasFlag(wxSP_LIVE_UPDATE); } bool wxSplitterWindow::Create(wxWindow *parent, wxWindowID id, From fffe7f717001d02be9c185938a3e06e39bc9d3a4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Dec 2023 19:23:40 +0100 Subject: [PATCH 139/257] Make using non-live resize work in wxAUI work in more cases Use wxClientDC instead of wxScreenDC, which only works in wxMSW, and use wxINVERT instead of wxXOR, to make DrawResizeHint() actually draw something in wxGTK3 too. And not using wxScreenDC might even help with some problems under MSW too, see #23982. Note that "rectangle hint" code still uses wxScreenDC, but this hint kind should probably be just removed as it doesn't seem useful for anything. --- src/aui/framemanager.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 43f24e2933..3d8af0aeb3 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -279,16 +279,21 @@ static wxBitmap wxPaneCreateStippleBitmap() static void DrawResizeHint(wxDC& dc, const wxRect& rect) { +#ifdef __WXMSW__ wxBitmap stipple = wxPaneCreateStippleBitmap(); wxBrush brush(stipple); dc.SetBrush(brush); -#ifdef __WXMSW__ wxMSWDCImpl *impl = (wxMSWDCImpl*) dc.GetImpl(); PatBlt(GetHdcOf(*impl), rect.GetX(), rect.GetY(), rect.GetWidth(), rect.GetHeight(), PATINVERT); #else - dc.SetPen(*wxTRANSPARENT_PEN); + // Note that we have to use white colour for wxINVERT to work with + // wxGraphicsContext-based wxDC implementations, such as used by wxGTK3 + // (and wxOSX, but this code is never used for the latter because it always + // uses live resize). + dc.SetPen(*wxWHITE_PEN); + dc.SetBrush(*wxWHITE_BRUSH); - dc.SetLogicalFunction(wxXOR); + dc.SetLogicalFunction(wxINVERT); dc.DrawRectangle(rect); #endif } @@ -4469,7 +4474,7 @@ void wxAuiManager::OnLeftUp(wxMouseEvent& event) if (!HasLiveResize()) { // get rid of the hint rectangle - wxScreenDC dc; + wxClientDC dc{m_frame}; DrawResizeHint(dc, m_actionHintRect); } if (m_currentDragItem != -1 && HasLiveResize()) @@ -4584,9 +4589,8 @@ void wxAuiManager::OnMotion(wxMouseEvent& event) } else { - wxRect rect(m_frame->ClientToScreen(pos), - m_actionPart->rect.GetSize()); - wxScreenDC dc; + wxRect rect(pos, m_actionPart->rect.GetSize()); + wxClientDC dc{m_frame}; if (!m_actionHintRect.IsEmpty()) { @@ -4595,13 +4599,9 @@ void wxAuiManager::OnMotion(wxMouseEvent& event) m_actionHintRect = wxRect(); } - // draw new resize hint, if it's inside the managed frame - wxRect frameScreenRect = m_frame->GetScreenRect(); - if (frameScreenRect.Contains(rect)) - { - DrawResizeHint(dc, rect); - m_actionHintRect = rect; - } + // draw new resize hint + DrawResizeHint(dc, rect); + m_actionHintRect = rect; } } } From 3e32e0fa678e4d314a050c24f5f067df14c1493d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Dec 2023 19:26:42 +0100 Subject: [PATCH 140/257] Allow using non-live resize in wxAUI with wxGTK3/X11 In this case we can still use wxClientDC, so let people do it if they really want to for consistency with wxSplitterWindow and because it doesn't really cost us anything. --- include/wx/aui/framemanager.h | 2 +- interface/wx/aui/framemanager.h | 10 ++++++--- src/aui/framemanager.cpp | 36 +++++++++++++-------------------- 3 files changed, 22 insertions(+), 26 deletions(-) diff --git a/include/wx/aui/framemanager.h b/include/wx/aui/framemanager.h index 167c486c35..0533a5b6f2 100644 --- a/include/wx/aui/framemanager.h +++ b/include/wx/aui/framemanager.h @@ -417,7 +417,7 @@ public: void SetFlags(unsigned int flags); unsigned int GetFlags() const; - static bool AlwaysUsesLiveResize(); + static bool AlwaysUsesLiveResize(const wxWindow* window = nullptr); bool HasLiveResize() const; void SetManagedWindow(wxWindow* managedWnd); diff --git a/interface/wx/aui/framemanager.h b/interface/wx/aui/framemanager.h index 549492f354..832b0282c8 100644 --- a/interface/wx/aui/framemanager.h +++ b/interface/wx/aui/framemanager.h @@ -219,12 +219,16 @@ public: If this function returns true, ::wxAUI_MGR_LIVE_RESIZE flag is ignored and live resize is always used, whether it's specified or not. - Currently this is the case for wxOSX and wxGTK3 ports, as live resizing - is the only implemented method there. + Currently this is the case for wxOSX and wxGTK3 when using Wayland, as + live resizing is the only implemented method there. See + wxClientDC::CanBeUsedForDrawing() for more details. + + @param window The associated window, may be null (this parameter was + added in wxWidgets 3.3.0) @since 3.1.4 */ - static bool AlwaysUsesLiveResize(); + static bool AlwaysUsesLiveResize(const wxWindow* window); /** This function is used by controls to calculate the drop hint rectangle. diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 3d8af0aeb3..793e9498be 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -767,26 +767,17 @@ unsigned int wxAuiManager::GetFlags() const return m_flags; } -// With Core Graphics on Mac or GTK 3, it's not possible to show sash feedback, -// so we'll always use live update instead. -#if defined(__WXMAC__) || defined(__WXGTK3__) - #define wxUSE_AUI_LIVE_RESIZE_ALWAYS 1 -#else - #define wxUSE_AUI_LIVE_RESIZE_ALWAYS 0 -#endif - -/* static */ bool wxAuiManager::AlwaysUsesLiveResize() +/* static */ bool wxAuiManager::AlwaysUsesLiveResize(const wxWindow* window) { - return wxUSE_AUI_LIVE_RESIZE_ALWAYS; + // Not using live resize relies on wxClientDC being usable for drawing, so + // we have to use live resize if it can't be used on the current platform. + return !wxClientDC::CanBeUsedForDrawing(window); } bool wxAuiManager::HasLiveResize() const { -#if wxUSE_AUI_LIVE_RESIZE_ALWAYS - return true; -#else - return (GetFlags() & wxAUI_MGR_LIVE_RESIZE) == wxAUI_MGR_LIVE_RESIZE; -#endif + return AlwaysUsesLiveResize(m_frame) || + (GetFlags() & wxAUI_MGR_LIVE_RESIZE) == wxAUI_MGR_LIVE_RESIZE; } // don't use these anymore as they are deprecated @@ -3925,15 +3916,16 @@ void wxAuiManager::Repaint(wxDC* dc) // make a client dc if (!dc) { -#if wxUSE_AUI_LIVE_RESIZE_ALWAYS - // We can't use wxClientDC in these ports. - m_frame->Refresh() ; - m_frame->Update() ; - return ; -#else + if ( AlwaysUsesLiveResize(m_frame) ) + { + // We can't use wxClientDC in these ports. + m_frame->Refresh() ; + m_frame->Update() ; + return ; + } + client_dc.reset(new wxClientDC(m_frame)); dc = client_dc.get(); -#endif } int w, h; From 15af32035311dcf5c1b22b8ba05aa861c3682a00 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 26 Dec 2023 19:48:36 +0100 Subject: [PATCH 141/257] Fix updating wxAUI frame buttons on mouse hover This didn't work under wxOSX or wxGTK/Wayland as it used wxClientDC which doesn't work in these ports. Fix this in the usual way, i.e. by just redrawing everything in them. --- src/aui/framemanager.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/aui/framemanager.cpp b/src/aui/framemanager.cpp index 793e9498be..3fe78a8a3c 100644 --- a/src/aui/framemanager.cpp +++ b/src/aui/framemanager.cpp @@ -4084,7 +4084,14 @@ void wxAuiManager::UpdateButtonOnScreen(wxAuiDockUIPart* button_ui_part, state = wxAUI_BUTTON_STATE_HOVER; } - // now repaint the button with hover state + // now repaint the button with hover state -- or everything if we can't + // repaint just it + if ( !wxClientDC::CanBeUsedForDrawing(m_frame) ) + { + m_frame->Refresh(); + m_frame->Update(); + } + wxClientDC cdc(m_frame); // if the frame has a toolbar, the client area From aa562ea2fb90b4c7376544beb2a532a4962d7c1a Mon Sep 17 00:00:00 2001 From: ali kettab Date: Sun, 17 Dec 2023 16:21:30 +0100 Subject: [PATCH 142/257] Get rid of QtCreateControl() from wxQt code base If possible, all windows should call wxWindow::Create() on creation now, because among other things: - It manages generic and non-generic windows uniformly and transparently - It ensures an appropriate initial size for the window - AddChild() and PostCreation() are automatically called - Scrollbar policies are set in one place. --- include/wx/qt/control.h | 7 --- include/wx/qt/frame.h | 1 - include/wx/qt/listbox.h | 1 - include/wx/qt/textctrl.h | 1 - include/wx/qt/window.h | 5 +- src/qt/button.cpp | 2 +- src/qt/calctrl.cpp | 2 +- src/qt/checkbox.cpp | 2 +- src/qt/choice.cpp | 2 +- src/qt/combobox.cpp | 2 +- src/qt/control.cpp | 34 ------------- src/qt/datectrl.cpp | 2 +- src/qt/dialog.cpp | 7 +-- src/qt/frame.cpp | 36 +++---------- src/qt/gauge.cpp | 2 +- src/qt/listbox.cpp | 9 ++-- src/qt/listctrl.cpp | 5 +- src/qt/menu.cpp | 12 +++-- src/qt/msgdlg.cpp | 2 +- src/qt/notebook.cpp | 2 +- src/qt/radiobox.cpp | 2 +- src/qt/radiobut.cpp | 2 +- src/qt/scrolbar.cpp | 2 +- src/qt/slider.cpp | 4 +- src/qt/spinbutt.cpp | 2 +- src/qt/spinctrl.cpp | 2 +- src/qt/statbmp.cpp | 2 +- src/qt/statbox.cpp | 2 +- src/qt/statline.cpp | 2 +- src/qt/stattext.cpp | 5 +- src/qt/statusbar.cpp | 4 +- src/qt/textctrl.cpp | 17 ++----- src/qt/tglbtn.cpp | 2 +- src/qt/timectrl.cpp | 2 +- src/qt/toolbar.cpp | 13 +++-- src/qt/toplevel.cpp | 20 ++------ src/qt/treectrl.cpp | 12 +++-- src/qt/window.cpp | 107 +++++++++++++++++++++++++++++---------- 38 files changed, 156 insertions(+), 182 deletions(-) diff --git a/include/wx/qt/control.h b/include/wx/qt/control.h index 7483292594..f4ccca7c81 100644 --- a/include/wx/qt/control.h +++ b/include/wx/qt/control.h @@ -24,13 +24,6 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString& name = wxASCII_STR(wxControlNameStr)); - virtual wxSize DoGetBestSize() const override; - -protected: - bool QtCreateControl( wxWindow *parent, wxWindowID id, const wxPoint &pos, - const wxSize &size, long style, const wxValidator &validator, - const wxString &name ); - private: wxDECLARE_DYNAMIC_CLASS(wxControl); }; diff --git a/include/wx/qt/frame.h b/include/wx/qt/frame.h index b538df7ddb..ccf652cc38 100644 --- a/include/wx/qt/frame.h +++ b/include/wx/qt/frame.h @@ -13,7 +13,6 @@ #include "wx/frame.h" class QMainWindow; -class QAbstractScrollArea; class WXDLLIMPEXP_CORE wxFrame : public wxFrameBase { diff --git a/include/wx/qt/listbox.h b/include/wx/qt/listbox.h index 6607c95bd1..58e8358111 100644 --- a/include/wx/qt/listbox.h +++ b/include/wx/qt/listbox.h @@ -10,7 +10,6 @@ class QListWidget; class QModelIndex; -class QAbstractScrollArea; class WXDLLIMPEXP_CORE wxListBox : public wxListBoxBase { diff --git a/include/wx/qt/textctrl.h b/include/wx/qt/textctrl.h index 389421b02e..48b7ec46a8 100644 --- a/include/wx/qt/textctrl.h +++ b/include/wx/qt/textctrl.h @@ -8,7 +8,6 @@ #ifndef _WX_QT_TEXTCTRL_H_ #define _WX_QT_TEXTCTRL_H_ -class QAbstractScrollArea; class wxQtEdit; class WXDLLIMPEXP_CORE wxTextCtrl : public wxTextCtrlBase diff --git a/include/wx/qt/window.h b/include/wx/qt/window.h index 2fb91ee162..b0f55efb33 100644 --- a/include/wx/qt/window.h +++ b/include/wx/qt/window.h @@ -66,7 +66,8 @@ public: long style = 0, const wxString& name = wxASCII_STR(wxPanelNameStr)); - // Used by all window classes in the widget creation process. + // Derived classes have to call PostCreation() explicitly if they don't call + // our Create() method during widget creation process. void PostCreation( bool generic = true ); void AddChild( wxWindowBase *child ) override; @@ -202,6 +203,8 @@ protected: virtual void DoSetClientSize(int width, int height) override; virtual void DoGetClientSize(int *width, int *height) const override; + virtual wxSize DoGetBestSize() const override; + virtual void DoMoveWindow(int x, int y, int width, int height) override; #if wxUSE_TOOLTIPS diff --git a/src/qt/button.cpp b/src/qt/button.cpp index 630b9bf7a4..9262810364 100644 --- a/src/qt/button.cpp +++ b/src/qt/button.cpp @@ -44,7 +44,7 @@ bool wxButton::Create(wxWindow *parent, wxWindowID id, QtCreate(parent); SetLabel( label.IsEmpty() && wxIsStockID( id ) ? wxGetStockLabel( id ) : label ); - return QtCreateControl( parent, id, pos, size, style, validator, name ); + return wxButtonBase::Create( parent, id, pos, size, style, validator, name ); } wxWindow *wxButton::SetDefault() diff --git a/src/qt/calctrl.cpp b/src/qt/calctrl.cpp index d98f38e24b..92e9bcb7c1 100644 --- a/src/qt/calctrl.cpp +++ b/src/qt/calctrl.cpp @@ -96,7 +96,7 @@ bool wxCalendarCtrl::Create(wxWindow *parent, wxWindowID id, const wxDateTime& d if ( date.IsValid() ) SetDate(date); - return QtCreateControl( parent, id, pos, size, style, wxDefaultValidator, name ); + return wxCalendarCtrlBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ); } void wxCalendarCtrl::UpdateStyle() diff --git a/src/qt/checkbox.cpp b/src/qt/checkbox.cpp index 89348045b9..71245afde4 100644 --- a/src/qt/checkbox.cpp +++ b/src/qt/checkbox.cpp @@ -66,7 +66,7 @@ bool wxCheckBox::Create(wxWindow *parent, wxWindowID id, const wxString& label, m_qtCheckBox->setText( wxQtConvertString( label ) ); // Do the initialization here as WXValidateStyle may fail in unit tests - bool ok = QtCreateControl( parent, id, pos, size, style, validator, name ); + bool ok = wxCheckBoxBase::Create( parent, id, pos, size, style, validator, name ); WXValidateStyle(&style); diff --git a/src/qt/choice.cpp b/src/qt/choice.cpp index fc04100d0f..5e66acee00 100644 --- a/src/qt/choice.cpp +++ b/src/qt/choice.cpp @@ -138,7 +138,7 @@ bool wxChoice::Create( wxWindow *parent, wxWindowID id, while ( n-- > 0 ) m_qtComboBox->addItem( wxQtConvertString( *choices++ )); - return QtCreateControl( parent, id, pos, size, style, validator, name ); + return wxChoiceBase::Create( parent, id, pos, size, style, validator, name ); } wxSize wxChoice::DoGetBestSize() const diff --git a/src/qt/combobox.cpp b/src/qt/combobox.cpp index 042d383328..ef3366ebea 100644 --- a/src/qt/combobox.cpp +++ b/src/qt/combobox.cpp @@ -149,7 +149,7 @@ bool wxComboBox::Create(wxWindow *parent, wxWindowID id, m_qtComboBox->addItem( wxQtConvertString( *choices++ )); m_qtComboBox->setCurrentText( wxQtConvertString( value )); - return QtCreateControl( parent, id, pos, size, style, validator, name ); + return wxChoiceBase::Create( parent, id, pos, size, style, validator, name ); } bool wxComboBox::IsReadOnly() const diff --git a/src/qt/control.cpp b/src/qt/control.cpp index 057619ab7a..cb3b60021d 100644 --- a/src/qt/control.cpp +++ b/src/qt/control.cpp @@ -43,37 +43,3 @@ bool wxControl::Create(wxWindow *parent, wxWindowID id, return isCreated; } - -bool wxControl::QtCreateControl( wxWindow *parent, wxWindowID id, - const wxPoint &pos, const wxSize &size, long style, - const wxValidator &validator, const wxString &name ) -{ - // The Qt widget has been created without a position/size so move/resize it: - - wxSize bestSize = GetBestSize(); - int width = ( size.GetWidth() == wxDefaultCoord ) ? bestSize.GetWidth() : size.GetWidth(); - int height = ( size.GetHeight() == wxDefaultCoord ) ? bestSize.GetHeight() : size.GetHeight(); - - DoMoveWindow( pos.x, pos.y, width, height ); - - // Let Qt handle the background: - SetBackgroundStyle(wxBG_STYLE_SYSTEM); - - if (!CreateControl( parent, id, pos, size, style, validator, name )) - return false; - - PostCreation(false); - return true; -} - -wxSize wxControl::DoGetBestSize() const -{ - wxSize minsize = wxQtConvertSize( GetHandle()->minimumSizeHint() ); - wxSize size = wxQtConvertSize( GetHandle()->sizeHint() ); - // best effort to ensure a correct size (note that some qt controls implement just one or both size hints) - if (size.GetWidth() < minsize.GetWidth()) - size.SetWidth(minsize.GetWidth()); - if (size.GetHeight() < minsize.GetHeight()) - size.SetHeight(minsize.GetHeight()); - return size; -} diff --git a/src/qt/datectrl.cpp b/src/qt/datectrl.cpp index 7a5bfa9018..81cd9b7faa 100644 --- a/src/qt/datectrl.cpp +++ b/src/qt/datectrl.cpp @@ -74,7 +74,7 @@ wxDatePickerCtrl::Create(wxWindow *parent, m_qtDateEdit->setCalendarPopup(style & wxDP_DROPDOWN); m_qtDateEdit->setDisplayFormat(QLocale::system().dateFormat(QLocale::ShortFormat)); - return QtCreateControl( parent, id, pos, size, style, validator, name ); + return wxDatePickerCtrlBase::Create( parent, id, pos, size, style, validator, name ); } // ---------------------------------------------------------------------------- diff --git a/src/qt/dialog.cpp b/src/qt/dialog.cpp index 7215fe4ed8..e25751435c 100644 --- a/src/qt/dialog.cpp +++ b/src/qt/dialog.cpp @@ -70,12 +70,7 @@ bool wxDialog::Create( wxWindow *parent, wxWindowID id, m_qtWindow->setWindowFlags(qtFlags); } - if ( !wxTopLevelWindow::Create( parent, id, title, pos, size, style, name ) ) - return false; - - PostCreation(); - - return true; + return wxTopLevelWindow::Create( parent, id, title, pos, size, style, name ); } int wxDialog::ShowModal() diff --git a/src/qt/frame.cpp b/src/qt/frame.cpp index 04688697f9..b443bc7064 100644 --- a/src/qt/frame.cpp +++ b/src/qt/frame.cpp @@ -60,13 +60,16 @@ bool wxFrame::Create( wxWindow *parent, wxWindowID id, const wxString& title, // QMainWindow takes ownership of the central widget pointer. // Not using QScrollArea or wxPanel is intentional here as it makes the - // implementation simpler and manageable. + // implementation simpler and more manageable. GetQMainWindow()->setCentralWidget( new wxQtCentralWidget( this, this ) ); if ( !wxFrameBase::Create( parent, id, title, pos, size, style, name ) ) + { return false; + } + + SetWindowStyleFlag(style); - PostCreation(); return true; } @@ -97,8 +100,6 @@ void wxFrame::SetStatusBar( wxStatusBar *statusBar ) if ( statusBar != nullptr ) { GetQMainWindow()->setStatusBar( statusBar->GetQStatusBar() ); - // Update statusbar sizes now that it has a size - statusBar->Refresh(); } else { @@ -213,35 +214,12 @@ void wxFrame::RemoveChild( wxWindowBase *child ) // excluding any menubar and toolbar if any. wxPoint wxFrame::GetClientAreaOrigin() const { - wxPoint pt = wxFrameBase::GetClientAreaOrigin(); - -#if wxUSE_MENUBAR - wxMenuBar * const menubar = GetMenuBar(); - if ( menubar && menubar->IsAttached() ) - pt.y += menubar->GetSize().y; -#endif // wxUSE_MENUBAR - - return pt; + return wxQtConvertPoint( GetQMainWindow()->centralWidget()->pos() ); } void wxFrame::DoGetClientSize(int *width, int *height) const { - wxWindow::DoGetClientSize(width, height); - - // Adjust the height, taking the status and menu bars into account, if any: - if ( height ) - { - if ( wxStatusBar *sb = GetStatusBar() ) - { - *height -= sb->GetSize().y; - } - - - if ( QWidget *qmb = GetQMainWindow()->menuWidget() ) - { - *height -= qmb->geometry().height(); - } - } + wxFrameBase::DoGetClientSize(width, height); } void wxFrame::DoSetClientSize(int width, int height) diff --git a/src/qt/gauge.cpp b/src/qt/gauge.cpp index b2852dfbb6..78b46c44b7 100644 --- a/src/qt/gauge.cpp +++ b/src/qt/gauge.cpp @@ -61,7 +61,7 @@ bool wxGauge::Create(wxWindow *parent, m_qtProgressBar->setTextVisible( style & wxGA_TEXT ); m_qtProgressBar->setValue(0); - return QtCreateControl( parent, id, pos, size, style, validator, name ); + return wxControl::Create( parent, id, pos, size, style, validator, name ); } diff --git a/src/qt/listbox.cpp b/src/qt/listbox.cpp index 4ec9f37936..7057a729c3 100644 --- a/src/qt/listbox.cpp +++ b/src/qt/listbox.cpp @@ -137,7 +137,9 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id, } m_qtListWidget->addItem(item); } - return wxListBoxBase::Create( parent, id, pos, size, style, validator, name ); + return wxListBoxBase::Create( parent, id, pos, size, + style | wxVSCROLL | wxHSCROLL, + validator, name ); } bool wxListBox::Create(wxWindow *parent, wxWindowID id, @@ -170,7 +172,9 @@ bool wxListBox::Create(wxWindow *parent, wxWindowID id, m_qtListWidget->addItem(item); } - return wxListBoxBase::Create( parent, id, pos, size, style, validator, name ); + return wxListBoxBase::Create( parent, id, pos, size, + style | wxVSCROLL | wxHSCROLL, + validator, name ); } void wxListBox::DoCreate(wxWindow* parent, long style) @@ -178,7 +182,6 @@ void wxListBox::DoCreate(wxWindow* parent, long style) Init(); m_qtWindow = - m_qtContainer = m_qtListWidget = new wxQtListWidget( parent, this ); if ( style & wxLB_SORT ) diff --git a/src/qt/listctrl.cpp b/src/qt/listctrl.cpp index 19b32d3228..1308d84789 100644 --- a/src/qt/listctrl.cpp +++ b/src/qt/listctrl.cpp @@ -1347,6 +1347,7 @@ bool wxListCtrl::Create(wxWindow *parent, ? new wxQtVirtualListModel(this) : new wxQtListModel(this); + m_qtWindow = m_qtTreeWidget = new wxQtListTreeWidget(parent, this); m_qtTreeWidget->setModel(m_model); m_model->SetView(m_qtTreeWidget); @@ -1355,7 +1356,9 @@ bool wxListCtrl::Create(wxWindow *parent, m_qtTreeWidget->setSelectionBehavior(QAbstractItemView::SelectRows); m_qtTreeWidget->setTabKeyNavigation(true); - if ( !QtCreateControl(parent, id, pos, size, style, validator, name) ) + if ( !wxListCtrlBase::Create(parent, id, pos, size, + style | wxVSCROLL | wxHSCROLL, + validator, name) ) return false; SetWindowStyleFlag(style); diff --git a/src/qt/menu.cpp b/src/qt/menu.cpp index 8907faed67..4e577fc884 100644 --- a/src/qt/menu.cpp +++ b/src/qt/menu.cpp @@ -213,23 +213,25 @@ QMenu *wxMenu::GetHandle() const wxMenuBar::wxMenuBar() { m_qtMenuBar = new QMenuBar(); - PostCreation(false); + + wxMenuBarBase::Create(nullptr, wxID_ANY); } -wxMenuBar::wxMenuBar( long WXUNUSED( style )) +wxMenuBar::wxMenuBar( long style ) { m_qtMenuBar = new QMenuBar(); - PostCreation(false); + + wxMenuBarBase::Create(nullptr, wxID_ANY, wxDefaultPosition, wxDefaultSize, style); } -wxMenuBar::wxMenuBar(size_t count, wxMenu *menus[], const wxString titles[], long WXUNUSED( style )) +wxMenuBar::wxMenuBar(size_t count, wxMenu *menus[], const wxString titles[], long style) { m_qtMenuBar = new QMenuBar(); for ( size_t i = 0; i < count; ++i ) Append( menus[ i ], titles[ i ] ); - PostCreation(false); + wxMenuBarBase::Create(nullptr, wxID_ANY, wxDefaultPosition, wxDefaultSize, style); } diff --git a/src/qt/msgdlg.cpp b/src/qt/msgdlg.cpp index 803c78205b..22251b0533 100644 --- a/src/qt/msgdlg.cpp +++ b/src/qt/msgdlg.cpp @@ -109,7 +109,7 @@ wxMessageDialog::wxMessageDialog( wxWindow *parent, const wxString& message, if ( style & wxSTAY_ON_TOP ) dlg->setWindowModality( Qt::ApplicationModal ); - PostCreation(); + PostCreation(false); Centre(wxBOTH | wxCENTER_FRAME); } diff --git a/src/qt/notebook.cpp b/src/qt/notebook.cpp index dbd3fc601f..9e111cf8f3 100644 --- a/src/qt/notebook.cpp +++ b/src/qt/notebook.cpp @@ -75,7 +75,7 @@ bool wxNotebook::Create(wxWindow *parent, { m_qtTabWidget = new wxQtTabWidget( parent, this ); - if ( !QtCreateControl( parent, id, pos, size, style, wxDefaultValidator, name ) ) + if ( !wxControl::Create( parent, id, pos, size, style, wxDefaultValidator, name ) ) return false; if ( m_windowStyle & wxBK_RIGHT ) diff --git a/src/qt/radiobox.cpp b/src/qt/radiobox.cpp index 756c0d06e5..c9e473b80d 100644 --- a/src/qt/radiobox.cpp +++ b/src/qt/radiobox.cpp @@ -196,7 +196,7 @@ bool wxRadioBox::Create(wxWindow *parent, m_qtGroupBox->setLayout(horzLayout); SetMajorDim(majorDim == 0 ? n : majorDim, style); - return QtCreateControl( parent, id, pos, size, style, val, name ); + return wxControl::Create( parent, id, pos, size, style, val, name ); } static QAbstractButton *GetButtonAt( const QButtonGroup *group, unsigned int n ) diff --git a/src/qt/radiobut.cpp b/src/qt/radiobut.cpp index de48011eda..8621d5760b 100644 --- a/src/qt/radiobut.cpp +++ b/src/qt/radiobut.cpp @@ -127,7 +127,7 @@ bool wxRadioButton::Create( wxWindow *parent, m_qtRadioButton = new wxQtRadioButton( parent, this ); m_qtRadioButton->setText( wxQtConvertString( label )); - if ( !QtCreateControl(parent, id, pos, size, style, validator, name) ) + if ( !wxRadioButtonBase::Create(parent, id, pos, size, style, validator, name) ) return false; // Check if we need to create a new button group: this must be done when diff --git a/src/qt/scrolbar.cpp b/src/qt/scrolbar.cpp index 44caa965b6..111a551c1c 100644 --- a/src/qt/scrolbar.cpp +++ b/src/qt/scrolbar.cpp @@ -52,7 +52,7 @@ bool wxScrollBar::Create( wxWindow *parent, wxWindowID id, m_qtScrollBar = new wxQtScrollBar( parent, this ); m_qtScrollBar->setOrientation( wxQtConvertOrientation( style, wxSB_HORIZONTAL )); - return QtCreateControl( parent, id, pos, size, style, validator, name ); + return wxScrollBarBase::Create( parent, id, pos, size, style, validator, name ); } int wxScrollBar::GetThumbPosition() const diff --git a/src/qt/slider.cpp b/src/qt/slider.cpp index 8396d969b5..c9be3c40d0 100644 --- a/src/qt/slider.cpp +++ b/src/qt/slider.cpp @@ -174,10 +174,10 @@ bool wxSlider::Create(wxWindow *parent, SetValue( value ); SetPageSize(wxMax(1, (maxValue - minValue) / 10)); - if ( !QtCreateControl( parent, id, pos, size, style, validator, name ) ) + if ( !wxSliderBase::Create( parent, id, pos, size, style, validator, name ) ) return false; - // SetTick() needs the window style which is normally set after QtCreateControl() + // SetTick() needs the window style which is normally set after wxSliderBase::Create() // is called. Pass 0 as tickPos parameter is not used by Qt anyhow. SetTick( 0 ); diff --git a/src/qt/spinbutt.cpp b/src/qt/spinbutt.cpp index 7cd44195af..d866acca68 100644 --- a/src/qt/spinbutt.cpp +++ b/src/qt/spinbutt.cpp @@ -91,7 +91,7 @@ bool wxSpinButton::Create(wxWindow *parent, wxSize newSize( size ); newSize.SetWidth( 18 ); - return QtCreateControl( parent, id, pos, newSize, style, wxDefaultValidator, name ); + return wxSpinButtonBase::Create( parent, id, pos, newSize, style, wxDefaultValidator, name ); } void wxSpinButton::SetRange(int min, int max) diff --git a/src/qt/spinctrl.cpp b/src/qt/spinctrl.cpp index ef8f58b317..e38339572f 100644 --- a/src/qt/spinctrl.cpp +++ b/src/qt/spinctrl.cpp @@ -56,7 +56,7 @@ bool wxSpinCtrlQt< T, Widget >::Create( wxWindow *parent, wxWindowID id, if ( !value.IsEmpty() ) SetValue( value ); - return QtCreateControl( parent, id, pos, size, style, wxDefaultValidator, name ); + return wxSpinCtrlBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ); } template< typename T, typename Widget > diff --git a/src/qt/statbmp.cpp b/src/qt/statbmp.cpp index fdca00d07f..68860043ba 100644 --- a/src/qt/statbmp.cpp +++ b/src/qt/statbmp.cpp @@ -52,7 +52,7 @@ bool wxStaticBitmap::Create( wxWindow *parent, m_qtLabel = new wxQtStaticBmp( parent, this ); SetBitmap( label ); - return QtCreateControl( parent, id, pos, size, style, wxDefaultValidator, name ); + return wxStaticBitmapBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ); } static void SetPixmap( QLabel *label, const QPixmap *pixMap ) diff --git a/src/qt/statbox.cpp b/src/qt/statbox.cpp index 9fb44e6f1b..d4e8af0944 100644 --- a/src/qt/statbox.cpp +++ b/src/qt/statbox.cpp @@ -48,7 +48,7 @@ bool wxStaticBox::Create(wxWindow *parent, wxWindowID id, m_qtGroupBox = new wxQtGroupBox( parent, this ); m_qtGroupBox->setTitle( wxQtConvertString( label ) ); - return QtCreateControl( parent, id, pos, size, style, wxDefaultValidator, name ); + return wxStaticBoxBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ); } QWidget *wxStaticBox::GetHandle() const diff --git a/src/qt/statline.cpp b/src/qt/statline.cpp index 0e427a939a..07a8ff3a0a 100644 --- a/src/qt/statline.cpp +++ b/src/qt/statline.cpp @@ -40,7 +40,7 @@ bool wxStaticLine::Create( wxWindow *parent, else if ( style & wxLI_VERTICAL ) m_qtFrame->setFrameStyle( QFrame::VLine ); - return QtCreateControl( parent, id, pos, size, style, wxDefaultValidator, name ); + return wxStaticLineBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ); } QWidget *wxStaticLine::GetHandle() const diff --git a/src/qt/stattext.cpp b/src/qt/stattext.cpp index 5b30c56e47..54224088ff 100644 --- a/src/qt/stattext.cpp +++ b/src/qt/stattext.cpp @@ -63,12 +63,9 @@ bool wxStaticText::Create(wxWindow *parent, else m_qtLabel->setAlignment(Qt::AlignLeft); - if ( !QtCreateControl(parent, id, pos, size, style, wxDefaultValidator, name) ) - return false; - SetLabel(label); - return true; + return wxStaticTextBase::Create(parent, id, pos, size, style, wxDefaultValidator, name); } void wxStaticText::SetLabel(const wxString& label) diff --git a/src/qt/statusbar.cpp b/src/qt/statusbar.cpp index 750b323ec3..82450d2419 100644 --- a/src/qt/statusbar.cpp +++ b/src/qt/statusbar.cpp @@ -43,15 +43,13 @@ bool wxStatusBar::Create(wxWindow *parent, wxWindowID id, { m_qtStatusBar = new wxQtStatusBar( parent, this ); - if ( !QtCreateControl( parent, id, wxDefaultPosition, wxDefaultSize, + if ( !wxStatusBarBase::Create( parent, id, wxDefaultPosition, wxDefaultSize, style, wxDefaultValidator, name ) ) return false; if ( style & wxSTB_SIZEGRIP ) m_qtStatusBar->setSizeGripEnabled(true); - PostCreation(); - SetFieldsCount(1); // Notice that child controls, if any, will be added using addWidget() in diff --git a/src/qt/textctrl.cpp b/src/qt/textctrl.cpp index 45ce4d4509..4a75ea647b 100644 --- a/src/qt/textctrl.cpp +++ b/src/qt/textctrl.cpp @@ -676,19 +676,12 @@ bool wxTextCtrl::Create(wxWindow *parent, m_qtEdit->SetStyleFlags(style); - m_qtWindow = - m_qtContainer = m_qtEdit->ScrollBarsContainer(); + m_qtWindow = m_qtEdit->ScrollBarsContainer(); - if ( QtCreateControl( parent, id, pos, size, style, validator, name ) ) - { - // set the initial text value without sending the event: - // (done here as needs CreateBase called to set flags for IsMultiLine) - ChangeValue( value ); - // set the default inner color (white), as it is replaced by PostCreation - SetBackgroundColour( wxSystemSettingsNative::GetColour( wxSYS_COLOUR_LISTBOX ) ); - return true; - } - return false; + // set the initial text value without sending the event + ChangeValue( value ); + + return wxTextCtrlBase::Create( parent, id, pos, size, style, validator, name ); } wxTextCtrl::~wxTextCtrl() diff --git a/src/qt/tglbtn.cpp b/src/qt/tglbtn.cpp index ad48b089e0..b873d014b7 100644 --- a/src/qt/tglbtn.cpp +++ b/src/qt/tglbtn.cpp @@ -101,7 +101,7 @@ bool wxToggleButton::Create(wxWindow *parent, // this button is toggleable and has a text label SetLabel( wxIsStockID( id ) ? wxGetStockLabel( id ) : label ); - return QtCreateControl( parent, id, pos, size, style, validator, name ); + return wxToggleButtonBase::Create( parent, id, pos, size, style, validator, name ); } void wxToggleButton::SetValue(bool state) diff --git a/src/qt/timectrl.cpp b/src/qt/timectrl.cpp index 0b990e2571..9abb579dc0 100644 --- a/src/qt/timectrl.cpp +++ b/src/qt/timectrl.cpp @@ -75,7 +75,7 @@ wxTimePickerCtrl::Create(wxWindow *parent, wxQtConvertTime(wxDateTime::Now()) ); m_qtTimeEdit->setDisplayFormat(QLocale::system().timeFormat(QLocale::ShortFormat)); - return QtCreateControl( parent, id, pos, size, style, validator, name ); + return wxTimePickerCtrlBase::Create( parent, id, pos, size, style, validator, name ); } // ---------------------------------------------------------------------------- diff --git a/src/qt/toolbar.cpp b/src/qt/toolbar.cpp index ebcf301b88..e1aaa729b0 100644 --- a/src/qt/toolbar.cpp +++ b/src/qt/toolbar.cpp @@ -167,15 +167,14 @@ bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, m_qtToolBar = new wxQtToolbar( parent, this ); m_qtToolBar->setWindowTitle( wxQtConvertString( name ) ); + if ( !wxControl::Create( parent, id, pos, size, style, wxDefaultValidator, name ) ) + { + return false; + } + SetWindowStyleFlag(style); - // not calling to wxWindow::Create, so do the rest of initialization: - if (parent) - parent->AddChild( this ); - - PostCreation(); - - return wxWindowBase::CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ); + return true; } wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord WXUNUSED(x), diff --git a/src/qt/toplevel.cpp b/src/qt/toplevel.cpp index 33a0666b5a..5a702c8e9a 100644 --- a/src/qt/toplevel.cpp +++ b/src/qt/toplevel.cpp @@ -29,35 +29,23 @@ wxTopLevelWindowQt::wxTopLevelWindowQt(wxWindow *parent, } bool wxTopLevelWindowQt::Create( wxWindow *parent, wxWindowID winId, - const wxString &title, const wxPoint &pos, const wxSize &sizeOrig, + const wxString &title, const wxPoint &pos, const wxSize &size, long style, const wxString &name ) { - wxSize size(sizeOrig); - if ( !size.IsFullySpecified() ) - size.SetDefaults( GetDefaultSize() ); - wxTopLevelWindows.Append( this ); - if (!CreateBase( parent, winId, pos, size, style, wxDefaultValidator, name )) + if (!wxWindow::Create( parent, winId, pos, size, style, name )) { wxFAIL_MSG( wxT("wxTopLevelWindowNative creation failed") ); return false; } - SetTitle( title ); - SetWindowStyleFlag( style ); - - if (pos != wxDefaultPosition) - m_qtWindow->move( pos.x, pos.y ); - - m_qtWindow->resize( wxQtConvertSize( size ) ); - // Prevent automatic deletion of Qt main window on close // (this should be the default, but left just fo enforce it) GetHandle()->setAttribute(Qt::WA_DeleteOnClose, false); - // not calling to wxWindow::Create, so do the rest of initialization: - if (parent) parent->AddChild( this ); + SetTitle( title ); + SetWindowStyleFlag( style ); return true; } diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 15a2f80c3e..a45afe6a8e 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -573,14 +573,20 @@ bool wxTreeCtrl::Create(wxWindow *parent, wxWindowID id, const wxValidator& validator, const wxString& name) { + m_qtWindow = m_qtTreeWidget = new wxQTreeWidget(parent, this); m_qtTreeWidget->header()->hide(); - SetWindowStyleFlag(style); - Bind(wxEVT_KEY_DOWN, &wxTreeCtrl::OnKeyDown, this); - return QtCreateControl(parent, id, pos, size, style, validator, name); + if ( !wxTreeCtrlBase::Create(parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, validator, name) ) + { + return false; + } + + SetWindowStyleFlag(style); + + return true; } wxTreeCtrl::~wxTreeCtrl() diff --git a/src/qt/window.cpp b/src/qt/window.cpp index c21440f87e..481c21080d 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -48,6 +49,15 @@ inline QWidget* wxQtGetDrawingWidget(QAbstractScrollArea* qtContainer, return qtWidget; } + +inline wxSize wxQtGetBestSize(QWidget* qtWidget) +{ + auto size = qtWidget->sizeHint(); + // best effort to ensure a correct size (note that some qt controls + // implement just one or both size hints) + size = size.expandedTo(qtWidget->minimumSizeHint()); + return wxQtConvertSize(size); +} } // Base Widget helper (no scrollbar, used by wxWindow) @@ -56,6 +66,19 @@ class wxQtWidget : public wxQtEventSignalHandler< QWidget, wxWindowQt > { public: wxQtWidget( wxWindowQt *parent, wxWindowQt *handler ); + + virtual QSize sizeHint() const override + { + // Make sure the window has a valid initial size because the default size of a + // generic control (e.g. wxPanel) is (0, 0) when created. Quoting the Qt docs: + // + // "Setting the size to QSize(0, 0) will cause the widget + // to not appear on screen. This also applies to windows." + // + // The value 20 seems to be the default for wxPanel under wxMSW. + return QSize(20, 20); + } + }; wxQtWidget::wxQtWidget( wxWindowQt *parent, wxWindowQt *handler ) @@ -361,55 +384,64 @@ bool wxWindowQt::Create( wxWindowQt * parent, wxWindowID id, const wxPoint & pos // that a generic control, like wxPanel, is being created, so we need a very // simple control as a base: - wxSize initialSize = size; + bool isGeneric = false; if ( GetHandle() == nullptr ) { + isGeneric = true; + if ( style & (wxHSCROLL | wxVSCROLL) ) { m_qtWindow = m_qtContainer = new wxQtScrollArea( parent, this ); - - // If wx[HV]SCROLL is not given, the corresponding scrollbar is not shown - // at all. Otherwise it may be shown only on demand (default) or always, if - // the wxALWAYS_SHOW_SB is specified. - Qt::ScrollBarPolicy horzPolicy = (style & wxHSCROLL) - ? HasFlag(wxALWAYS_SHOW_SB) - ? Qt::ScrollBarAlwaysOn - : Qt::ScrollBarAsNeeded - : Qt::ScrollBarAlwaysOff; - Qt::ScrollBarPolicy vertPolicy = (style & wxVSCROLL) - ? HasFlag(wxALWAYS_SHOW_SB) - ? Qt::ScrollBarAlwaysOn - : Qt::ScrollBarAsNeeded - : Qt::ScrollBarAlwaysOff; - - m_qtContainer->setHorizontalScrollBarPolicy( horzPolicy ); - m_qtContainer->setVerticalScrollBarPolicy( vertPolicy ); } else + { m_qtWindow = new wxQtWidget( parent, this ); + } + } + else + { + m_qtContainer = dynamic_cast(m_qtWindow); + } - // The default size of a generic control (e.g. wxPanel) is (0, 0) when created and - // is ignored by Qt unless the widget is already assigned a valid size or is added - // to a QLayout to be managed with. The value 20 seems to be the default under wxMSW. - // Do not pass 'initialSize' to CreateBase() below, as it will be taken as the minimum - // size of the control, which is not the intention here. - initialSize.SetDefaults(wxSize(20, 20)); + if ( m_qtContainer ) + { + // If wx[HV]SCROLL is not given, the corresponding scrollbar is not shown + // at all. Otherwise it may be shown only on demand (default) or always, if + // the wxALWAYS_SHOW_SB is specified. + Qt::ScrollBarPolicy horzPolicy = (style & wxHSCROLL) + ? HasFlag(wxALWAYS_SHOW_SB) + ? Qt::ScrollBarAlwaysOn + : Qt::ScrollBarAsNeeded + : Qt::ScrollBarAlwaysOff; + Qt::ScrollBarPolicy vertPolicy = (style & wxVSCROLL) + ? HasFlag(wxALWAYS_SHOW_SB) + ? Qt::ScrollBarAlwaysOn + : Qt::ScrollBarAsNeeded + : Qt::ScrollBarAlwaysOff; + + m_qtContainer->setHorizontalScrollBarPolicy( horzPolicy ); + m_qtContainer->setVerticalScrollBarPolicy( vertPolicy ); } if ( !wxWindowBase::CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) return false; - parent->AddChild( this ); + if ( parent ) + parent->AddChild( this ); wxPoint p; if ( pos != wxDefaultPosition ) p = pos; + wxSize initialSize = size; + initialSize.SetDefaults( IsTopLevel() ? wxTopLevelWindowBase::GetDefaultSize() + : wxQtGetBestSize( GetHandle() ) ); + DoMoveWindow( p.x, p.y, initialSize.GetWidth(), initialSize.GetHeight() ); - PostCreation(); + PostCreation( isGeneric ); return true; } @@ -644,7 +676,6 @@ bool wxWindowQt::SetFont( const wxFont &font ) if (GetHandle()) { GetHandle()->setFont( font.GetHandle() ); - return true; } return wxWindowBase::SetFont(font); @@ -697,6 +728,10 @@ void wxWindowQt::DoGetTextExtent(const wxString& string, int *x, int *y, int *de QWidget *wxWindowQt::QtGetClientWidget() const { + auto frame = wxDynamicCast(this, wxFrame); + if ( frame ) + return frame->GetQMainWindow()->centralWidget(); + return wxQtGetDrawingWidget(m_qtContainer, GetHandle()); } @@ -1086,6 +1121,24 @@ void wxWindowQt::DoSetClientSize(int width, int height) } } +wxSize wxWindowQt::DoGetBestSize() const +{ + const wxSize size = wxWindowBase::DoGetBestSize(); + + if ( dynamic_cast(GetHandle()) ) + { + return size; + } + + wxSize bestSize = wxQtGetBestSize( GetHandle() ); + if ( size.IsFullySpecified() ) + { + bestSize.IncTo(size); + } + + return bestSize; +} + void wxWindowQt::DoMoveWindow(int x, int y, int width, int height) { QWidget *qtWidget = GetHandle(); From 0fb1a74983064dfe3a513367512d544280bb75d5 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Tue, 26 Dec 2023 12:54:14 +0100 Subject: [PATCH 143/257] Fix Set{Back,Fore}groundColour() for wxFrame under wxQt Restrict the effect of these functions to the central widget only. Otherwise the menubar, toolbar and statusbar would also be affected. --- src/qt/window.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/window.cpp b/src/qt/window.cpp index 481c21080d..c88fca784d 100644 --- a/src/qt/window.cpp +++ b/src/qt/window.cpp @@ -1284,7 +1284,7 @@ bool wxWindowQt::SetBackgroundColour(const wxColour& colour) if ( !wxWindowBase::SetBackgroundColour(colour) ) return false; - QWidget *widget = GetHandle(); + QWidget *widget = QtGetParentWidget(); wxQtChangeRoleColour(widget->backgroundRole(), widget, colour); return true; @@ -1295,7 +1295,7 @@ bool wxWindowQt::SetForegroundColour(const wxColour& colour) if (!wxWindowBase::SetForegroundColour(colour)) return false; - QWidget *widget = GetHandle(); + QWidget *widget = QtGetParentWidget(); wxQtChangeRoleColour(widget->foregroundRole(), widget, colour); return true; From 0eaff271ed336065defb333ddffa23c68501555f Mon Sep 17 00:00:00 2001 From: ali kettab Date: Tue, 26 Dec 2023 16:55:34 +0100 Subject: [PATCH 144/257] Fix wxStaticBitmap not using correct bitmap size under wxQt --- src/qt/statbmp.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/qt/statbmp.cpp b/src/qt/statbmp.cpp index 68860043ba..fc68f33bef 100644 --- a/src/qt/statbmp.cpp +++ b/src/qt/statbmp.cpp @@ -63,16 +63,24 @@ static void SetPixmap( QLabel *label, const QPixmap *pixMap ) void wxStaticBitmap::SetBitmap(const wxBitmapBundle& bitmap) { + m_bitmapBundle = bitmap; + SetPixmap( m_qtLabel, bitmap.GetBitmapFor(this).GetHandle() ); + + InvalidateBestSize(); } wxBitmap wxStaticBitmap::GetBitmap() const { - const QPixmap* pix = m_qtLabel->pixmap(); - if ( pix != nullptr ) - return wxBitmap( *pix ); - else - return wxBitmap(); + wxBitmap bitmap = m_bitmapBundle.GetBitmapFor(this); + if ( !bitmap.IsOk() ) + { + const QPixmap* pix = m_qtLabel->pixmap(); + if ( pix != nullptr ) + bitmap = wxBitmap( *pix ); + } + + return bitmap; } QWidget *wxStaticBitmap::GetHandle() const From a0b0f524ff3c452c680d04c021a364f6f0e0d0f6 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Tue, 26 Dec 2023 17:15:47 +0100 Subject: [PATCH 145/257] Handle wxTextCtrl created with wxTE_DONTWRAP or wxTE_NO_VSCROLL under wxQt --- src/qt/textctrl.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/qt/textctrl.cpp b/src/qt/textctrl.cpp index 4a75ea647b..5ef3b3f7cf 100644 --- a/src/qt/textctrl.cpp +++ b/src/qt/textctrl.cpp @@ -367,6 +367,9 @@ public: if ( flags & wxTE_RICH || flags & wxTE_RICH2 ) m_edit->setAcceptRichText(true); + + if ( flags & wxTE_DONTWRAP ) + m_edit->setLineWrapMode(QTextEdit::NoWrap); } private: @@ -668,6 +671,11 @@ bool wxTextCtrl::Create(wxWindow *parent, if ( style & wxTE_MULTILINE ) { m_qtEdit = new wxQtMultiLineEdit(new wxQtTextEdit(parent, this)); + + if ( style & wxTE_NO_VSCROLL ) + style &= ~wxVSCROLL; + else + style |= wxVSCROLL; } else { From 5f62f302316d35ff48d57594ef388fe3394e920c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 27 Dec 2023 02:46:10 +0100 Subject: [PATCH 146/257] Use WaitForEventAt() in Grid::CellSelect test too Try making this test more robust as well as it also sporadically fails on AppVeyor. Also simplify it a bit, checking for each of the expected events in turn instead of checking for their total number at the end. --- tests/controls/gridtest.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 3f40f15bd6..97557eb5bc 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -557,22 +557,32 @@ TEST_CASE_METHOD(GridTestCase, "Grid::CellSelect", "[grid]") wxYield(); sim.MouseClick(); - wxYield(); - + if ( !WaitForEventAt(point, "mouse click to be processed", [&]() { + return cell.GetCount() != 0; + }) ) + return; CHECK(cell.GetCount() == 1); - cell.Clear(); m_grid->SetGridCursor(1, 1); + + CHECK(cell.GetCount() == 1); + cell.Clear(); + m_grid->GoToCell(1, 0); + CHECK(cell.GetCount() == 1); + cell.Clear(); + sim.MouseMove(point); wxYield(); sim.MouseDblClick(); - wxYield(); - - CHECK(cell.GetCount() == 3); + if ( !WaitForEventAt(point, "mouse double click to be processed", [&]() { + return cell.GetCount() != 0; + }) ) + return; + CHECK(cell.GetCount() == 1); #endif } From 378da09c8419f4486ea891fc0a3188d68e4f41ad Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 27 Dec 2023 02:56:20 +0100 Subject: [PATCH 147/257] Fix typo in "receive" occurring a few times This is just too annoying to see. --- src/x11/clipbrd.cpp | 6 +++--- tests/net/webrequest.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/x11/clipbrd.cpp b/src/x11/clipbrd.cpp index f20d4a5782..3a13033fc8 100644 --- a/src/x11/clipbrd.cpp +++ b/src/x11/clipbrd.cpp @@ -38,7 +38,7 @@ typedef wxScopedArray wxDataFormatScopedArray; // copied in the src program. It will send an paste request, in x11, it will // send an event which type is SelectionRequest by XConvertSelection, then X // server will try to find a program that could handle SelectionRequest event. -// In src program, when recieve a SelectionRequest event, it will set the +// In src program, when receive a SelectionRequest event, it will set the // copied data to dest program's window property. More specific, the dest // program is called "requestor", the src program could find which window ask // for the data, through the event member : "event.xselection.requestor". @@ -117,7 +117,7 @@ typedef wxScopedArray wxDataFormatScopedArray; // If we want copy data to clipboard. We must own the XA_CLIPBOARD selection // through XSetSelectionOwner(). -// But the data is still host by src program. When src program recieve +// But the data is still host by src program. When src program receive // SelectionRequest event type. It set the data to requestor's window // property, through XCHangeProperty(xdisplay, requestor, ...). The second // parameter is the requests window. Requestor could find through XEvent. @@ -135,7 +135,7 @@ typedef wxScopedArray wxDataFormatScopedArray; // ----------------- // In SetData, due to x11 program does not send data to a gloabal clipboard, -// so the program hold the data, when the program recieve a SelectionRequest +// so the program hold the data, when the program receive a SelectionRequest // event, the program set the data to requestor's window property. So in the // implementation of SetData, it hold the wxDataObject that need to be paste. // And set XA_CLIPBOARD selection owner. diff --git a/tests/net/webrequest.cpp b/tests/net/webrequest.cpp index 129c93aa13..8ddeecf89c 100644 --- a/tests/net/webrequest.cpp +++ b/tests/net/webrequest.cpp @@ -127,7 +127,7 @@ public: void OnData(wxWebRequestEvent& evt) { - // Count all bytes recieved via data event for Storage_None + // Count all bytes received via data event for Storage_None dataSize += evt.GetDataSize(); } From c7fdb41fcdb5f8153268aea43995c2293c566ef0 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Wed, 27 Dec 2023 19:16:18 +0100 Subject: [PATCH 148/257] Implement wxNonOwnedWindow::SetShape() taking wxGraphicsPath under wxQt This is a copy and paste of wxMac's implementation to make wxRichToolTip work under wxQt. --- interface/wx/nonownedwnd.h | 4 ++-- src/qt/nonownedwnd.cpp | 27 ++++++++++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/interface/wx/nonownedwnd.h b/interface/wx/nonownedwnd.h index fde840b262..e91783c70b 100644 --- a/interface/wx/nonownedwnd.h +++ b/interface/wx/nonownedwnd.h @@ -62,8 +62,8 @@ public: resized using SetSize(). As the overload above, this method is not guaranteed to work on all - platforms but currently does work in wxMSW, wxOSX/Cocoa and wxGTK (with - the appropriate but almost always present X11 extensions) ports. + platforms but currently does work in wxMSW, wxOSX/Cocoa, wxGTK and wxQt + (with the appropriate but almost always present X11 extensions) ports. @since 2.9.3 */ diff --git a/src/qt/nonownedwnd.cpp b/src/qt/nonownedwnd.cpp index 7923c8f161..c8fe400a1a 100644 --- a/src/qt/nonownedwnd.cpp +++ b/src/qt/nonownedwnd.cpp @@ -18,12 +18,12 @@ #ifndef WX_PRECOMP - #include "wx/dcclient.h" - #include "wx/region.h" + #include "wx/dcmemory.h" #include "wx/region.h" #endif // WX_PRECOMP #include "wx/nonownedwnd.h" +#include "wx/graphics.h" #include "wx/qt/private/converter.h" #include "wx/qt/private/utils.h" @@ -57,10 +57,27 @@ bool wxNonOwnedWindow::DoSetRegionShape(const wxRegion& region) } #if wxUSE_GRAPHICS_CONTEXT -bool wxNonOwnedWindow::DoSetPathShape(const wxGraphicsPath& WXUNUSED(path)) +bool wxNonOwnedWindow::DoSetPathShape(const wxGraphicsPath& path) { - wxMISSING_IMPLEMENTATION( __FUNCTION__ ); - return true; + // Convert the path to wxRegion by rendering the path on a window-sized + // bitmap, creating a mask from it and finally creating the region from + // this mask. + wxBitmap bmp(GetSize()); + + { + wxMemoryDC dc(bmp); + dc.SetBackground(*wxBLACK_BRUSH); + dc.Clear(); + + std::unique_ptr context(wxGraphicsContext::Create(dc)); + context->SetBrush(*wxWHITE_BRUSH); + context->SetAntialiasMode(wxANTIALIAS_NONE); + context->FillPath(path); + } + + bmp.SetMask(new wxMask(bmp, *wxBLACK)); + + return DoSetRegionShape(wxRegion(bmp)); } #endif From 40a6d74aaf206fbde506fad0fea20e92b24582f4 Mon Sep 17 00:00:00 2001 From: ali kettab Date: Wed, 27 Dec 2023 19:31:33 +0100 Subject: [PATCH 149/257] Create the wxPopupWindow with a parent under wxQt The fact that we cannot create a wxPopupWindow with a parent is no longer valid after the recent changes to the wxQt port. The wxRichToolTip (an instance of wxPopupWindow) will crash if created without a parent under this port. --- src/qt/popupwin.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/qt/popupwin.cpp b/src/qt/popupwin.cpp index 1ebc46eb45..b9adaace09 100644 --- a/src/qt/popupwin.cpp +++ b/src/qt/popupwin.cpp @@ -42,9 +42,9 @@ wxPopupWindow::wxPopupWindow(wxWindow *parent, int flags) Create(parent, flags); } -bool wxPopupWindow::Create( wxWindow *WXUNUSED(parent), int style ) +bool wxPopupWindow::Create( wxWindow *parent, int style ) { - m_qtWindow = new wxQtPopupWindow(nullptr, this); + m_qtWindow = new wxQtPopupWindow(parent, this); m_qtWindow->setWindowFlag(Qt::Popup); m_qtWindow->setFocusPolicy(Qt::NoFocus); @@ -55,7 +55,6 @@ bool wxPopupWindow::Create( wxWindow *WXUNUSED(parent), int style ) // Unlike windows, top level windows are created hidden by default. m_isShown = false; - // Under wxQt, popups should be created without parent. Otherwise, the - // application would crash (caused by double deletion) when it's shut down. - return wxPopupWindowBase::Create( nullptr, style ); + return wxPopupWindowBase::Create(parent, style) && + wxWindow::Create( parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style ); } From 7dea9423c564592d8ea14ef728dec7103ac4a56f Mon Sep 17 00:00:00 2001 From: ali kettab Date: Wed, 27 Dec 2023 19:48:25 +0100 Subject: [PATCH 150/257] Fix wxPopupTransientWindow::Dismiss() implementation Remove installed event handlers before trying to hide the popup, as this could result in Destroy() being called twice under wxQt. This happens to wxRichToolTip for example. i.e. Destroy() is called once from wxPopupFocusHandler::OnKillFocus() after the call to Hide() then, from wxRichToolTipPopup::OnTimer(). --- src/common/popupcmn.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/popupcmn.cpp b/src/common/popupcmn.cpp index bf11efccbc..a0b9e8b721 100644 --- a/src/common/popupcmn.cpp +++ b/src/common/popupcmn.cpp @@ -431,8 +431,8 @@ bool wxPopupTransientWindow::Show( bool show ) void wxPopupTransientWindow::Dismiss() { - Hide(); PopHandlers(); + Hide(); } #if defined(__WXMAC__) && wxOSX_USE_COCOA_OR_CARBON From b2842601912169e6c3e5b124bb3bf5d886cf0be2 Mon Sep 17 00:00:00 2001 From: AliKet Date: Thu, 28 Dec 2023 16:35:23 +0100 Subject: [PATCH 151/257] Update interface/wx/nonownedwnd.h Co-authored-by: VZ --- interface/wx/nonownedwnd.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/wx/nonownedwnd.h b/interface/wx/nonownedwnd.h index e91783c70b..5232ce49f2 100644 --- a/interface/wx/nonownedwnd.h +++ b/interface/wx/nonownedwnd.h @@ -62,8 +62,8 @@ public: resized using SetSize(). As the overload above, this method is not guaranteed to work on all - platforms but currently does work in wxMSW, wxOSX/Cocoa, wxGTK and wxQt - (with the appropriate but almost always present X11 extensions) ports. + platforms but currently does work in wxMSW, wxOSX/Cocoa, wxGTK (with + the appropriate but almost always present X11 extensions) and wxQt ports. @since 2.9.3 */ From 6cb6cf1fde073a9d18ca84030a224610e3644171 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 28 Dec 2023 12:26:24 -0800 Subject: [PATCH 152/257] Use correct comparison for out-of-window mouse coordinate Coordinates on a window are 0..size-1 --- src/generic/scrlwing.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/generic/scrlwing.cpp b/src/generic/scrlwing.cpp index bcfb096d84..148722a598 100644 --- a/src/generic/scrlwing.cpp +++ b/src/generic/scrlwing.cpp @@ -955,12 +955,12 @@ void wxScrollHelperBase::HandleOnMouseLeave(wxMouseEvent& event) else // we're lower or to the right of the window { wxSize size = m_targetWindow->GetClientSize(); - if ( pt.x > size.x ) + if ( pt.x >= size.x ) { orient = wxHORIZONTAL; pos = m_xScrollLines; } - else if ( pt.y > size.y ) + else if ( pt.y >= size.y ) { orient = wxVERTICAL; pos = m_yScrollLines; From fc8a780932e6672646838b0c828626d63e04ffac Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 28 Dec 2023 12:32:59 -0800 Subject: [PATCH 153/257] Avoid applying "no-window" mouse coordinate conversion to generic wxWindow For a wxPizza widget in a GtkScrolledWindow, the coordinates are already correct. --- include/wx/gtk/private/event.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/wx/gtk/private/event.h b/include/wx/gtk/private/event.h index 851fd93710..9811422df3 100644 --- a/include/wx/gtk/private/event.h +++ b/include/wx/gtk/private/event.h @@ -62,7 +62,7 @@ template void InitMouseEvent(wxWindowGTK *win, // Some no-window widgets, notably GtkEntry on GTK3, have a GdkWindow // covering part of their area. Event coordinates from that window are // not relative to the widget, so do the conversion here. - if (!gtk_widget_get_has_window(win->m_widget) && + if (win->m_wxwindow == nullptr && !gtk_widget_get_has_window(win->m_widget) && gtk_widget_get_window(win->m_widget) == gdk_window_get_parent(gdk_event->window)) { GtkAllocation a; From ef326106c01fc74c98c13d56773b24ca3c4cb9e2 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 28 Dec 2023 12:39:41 -0800 Subject: [PATCH 154/257] Improve wxEVT_LEAVE_WINDOW generation while mouse is captured with GTK3 Non-integral coordinates and overlay scrollbars can cause the event to be generated with coordinates that are still inside the window. Avoid this by ensuring that integral coordinates are outside the window, and ignoring overlay scrollbars. Also remove gdk_display_flush(), contrary to the very old comment it does not seem to be necessary. Fixes wxScrolledWindow auto-scrolling. --- src/gtk/window.cpp | 58 +++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 05f62a87da..23d85f0b23 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -1968,27 +1968,54 @@ gtk_window_motion_notify_callback( GtkWidget * WXUNUSED(widget), if ( g_captureWindow ) { // synthesise a mouse enter or leave event if needed - GdkWindow* winUnderMouse = - wx_gdk_device_get_window_at_position(gdk_event->device, nullptr, nullptr); + GdkWindow* winUnderMouse = nullptr; + bool isOut = true; - GdkDisplay* display = winUnderMouse - ? gdk_window_get_display(winUnderMouse) - : nullptr; - if ( !display ) - display = gdk_display_get_default(); + if (gdk_event->x >= 0 && gdk_event->y >= 0) + { + const wxSize size(win->GetClientSize()); + if (gdk_event->x < size.x && gdk_event->y < size.y) + { + isOut = false; + winUnderMouse = + wx_gdk_device_get_window_at_position( + gdk_event->device, nullptr, nullptr); + } + } - // This seems to be necessary and actually been added to - // GDK itself in version 2.0.X - gdk_display_flush(display); + const bool hadMouse = g_captureWindowHasMouse; + g_captureWindowHasMouse = false; - bool hasMouse = winUnderMouse == gdk_event->window; - if ( hasMouse != g_captureWindowHasMouse ) + if (winUnderMouse == gdk_event->window) + g_captureWindowHasMouse = true; +#ifdef __WXGTK3__ + else if (winUnderMouse) + { + // Avoid treating overlay scrollbar as a different window + void* widgetUnderMouse; + gdk_window_get_user_data(winUnderMouse, &widgetUnderMouse); + if (GTK_IS_SCROLLBAR(widgetUnderMouse)) + { + GtkWidget* parent = gtk_widget_get_parent(GTK_WIDGET(widgetUnderMouse)); + if (parent == win->m_widget && GTK_IS_SCROLLED_WINDOW(parent)) + g_captureWindowHasMouse = true; + } + } +#endif + + if (g_captureWindowHasMouse != hadMouse) { // the mouse changed window - g_captureWindowHasMouse = hasMouse; - wxMouseEvent eventM(g_captureWindowHasMouse ? wxEVT_ENTER_WINDOW : wxEVT_LEAVE_WINDOW); + if (!g_captureWindowHasMouse && isOut) + { + // Ensure fractional coordinate is outside window when converted to int + if (gdk_event->x < 0) + gdk_event->x = floor(gdk_event->x); + if (gdk_event->y < 0) + gdk_event->y = floor(gdk_event->y); + } InitMouseEvent(win, eventM, gdk_event); eventM.SetEventObject(win); win->GTKProcessEvent(eventM); @@ -2001,10 +2028,9 @@ gtk_window_motion_notify_callback( GtkWidget * WXUNUSED(widget), // reset the event object and id in case win changed. event.SetEventObject( win ); event.SetId( win->GetId() ); - } - if ( !g_captureWindow ) SendSetCursorEvent(win, event.m_x, event.m_y); + } bool ret = win->GTKProcessEvent(event); From f1731fd6725338fa3d3f13e547fc5971e6abdf82 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 28 Dec 2023 12:49:47 -0800 Subject: [PATCH 155/257] Return index of first added image in wxImageList::Add() This is what MSW does. Broken in c374eefd34 (Fold wxOSX-specific wxImageList into generic version, 2018-10-30) See #10013 --- src/generic/imaglist.cpp | 3 ++- tests/graphics/imagelist.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/generic/imaglist.cpp b/src/generic/imaglist.cpp index 2a768cd12f..e78522633f 100644 --- a/src/generic/imaglist.cpp +++ b/src/generic/imaglist.cpp @@ -125,6 +125,7 @@ int wxGenericImageList::Add( const wxBitmap &bitmap ) // Cannot add image to invalid list wxCHECK_MSG( m_size != wxSize(0, 0), -1, "Invalid image list" ); + const int index = GetImageCount(); const wxSize bitmapSize = bitmap.GetSize(); // There is a special case: a bitmap may contain more than one image, @@ -155,7 +156,7 @@ int wxGenericImageList::Add( const wxBitmap &bitmap ) return -1; } - return GetImageCount() - 1; + return index; } int wxGenericImageList::Add( const wxBitmap& bitmap, const wxBitmap& mask ) diff --git a/tests/graphics/imagelist.cpp b/tests/graphics/imagelist.cpp index 4e564ff91a..7823009dfc 100644 --- a/tests/graphics/imagelist.cpp +++ b/tests/graphics/imagelist.cpp @@ -569,6 +569,14 @@ TEST_CASE_METHOD(ImageListTestCase, CHECK(HasMaskOrAlpha(bmp2)); CHECK(bmp2.GetSize() == BITMAP_SIZE); } + + SECTION("Add 2x width image") + { + il.RemoveAll(); + int idx = il.Add(wxBitmap(BITMAP_SIZE.x * 2, BITMAP_SIZE.y)); + CHECK(idx == 0); + CHECK(il.GetImageCount() == 2); + } } TEST_CASE("ImageList:NegativeTests", "[imagelist][negative]") From ce1d317768f7f187420997925f0fd1d4bfdc9a8e Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 28 Dec 2023 14:49:42 -0800 Subject: [PATCH 156/257] Remove GLU dependency See #23721 --- build/bakefiles/config.bkl | 6 +- build/cmake/init.cmake | 2 +- build/msw/makefile.gcc | 2 +- build/msw/makefile.vc | 2 +- build/msw/wx_gl.vcxproj | 10 +- build/tools/before_install.sh | 4 +- configure | 382 +------------------------ configure.ac | 22 +- docs/gtk/install.md | 4 +- include/wx/android/setup.h | 2 +- include/wx/gtk/setup.h | 2 +- include/wx/msw/setup.h | 2 +- include/wx/osx/setup.h | 2 +- include/wx/univ/setup.h | 2 +- interface/wx/glcanvas.h | 4 +- samples/opengl/cube/makefile.gcc | 2 +- samples/opengl/cube/makefile.vc | 2 +- samples/opengl/isosurf/isosurf.h | 3 - samples/opengl/isosurf/makefile.gcc | 2 +- samples/opengl/isosurf/makefile.vc | 2 +- samples/opengl/penguin/Makefile.in | 2 +- samples/opengl/penguin/dxfrenderer.cpp | 7 +- samples/opengl/penguin/makefile.gcc | 2 +- samples/opengl/penguin/makefile.unx | 2 +- samples/opengl/penguin/makefile.vc | 2 +- samples/opengl/penguin/penguin.bkl | 6 +- samples/opengl/penguin/penguin.cpp | 9 +- samples/opengl/pyramid/makefile.gcc | 2 +- samples/opengl/pyramid/makefile.vc | 2 +- src/msw/glcanvas.cpp | 1 - 30 files changed, 43 insertions(+), 451 deletions(-) diff --git a/build/bakefiles/config.bkl b/build/bakefiles/config.bkl index c0a4c94827..f94121b885 100644 --- a/build/bakefiles/config.bkl +++ b/build/bakefiles/config.bkl @@ -479,9 +479,9 @@ it if SHARED=1 unless you know what you are doing. - opengl32.lib glu32.lib - opengl32.lib glu32.lib - -lopengl32 -lglu32 + opengl32.lib + opengl32.lib + -lopengl32 diff --git a/build/cmake/init.cmake b/build/cmake/init.cmake index 5ba4b6165b..e229dcdd1c 100644 --- a/build/cmake/init.cmake +++ b/build/cmake/init.cmake @@ -411,7 +411,7 @@ if(wxUSE_GUI) else() find_package(OpenGL) if(OPENGL_FOUND) - foreach(gltarget OpenGL::GL OpenGL::GLU OpenGL::OpenGL) + foreach(gltarget OpenGL::GL OpenGL::OpenGL) if(TARGET ${gltarget}) set(OPENGL_LIBRARIES ${gltarget} ${OPENGL_LIBRARIES}) endif() diff --git a/build/msw/makefile.gcc b/build/msw/makefile.gcc index 1c91477dc5..0e041c137b 100644 --- a/build/msw/makefile.gcc +++ b/build/msw/makefile.gcc @@ -5956,7 +5956,7 @@ ifeq ($(USE_OPENGL),1) $(LIBDIRNAME)\wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl$(WXCOMPILER)$(VENDORTAG).dll: $(GLDLL_OBJECTS) $(LIBDIRNAME)\libwxexpat$(WXDEBUGFLAG).a $(LIBDIRNAME)\libwxzlib$(WXDEBUGFLAG).a $(LIBDIRNAME)\libwxregexu$(WXDEBUGFLAG).a $(__wxtiff___depname) $(__wxjpeg___depname) $(__wxpng___depname) $(__wxscintilla) $(__wxlexilla) $(OBJS)\gldll_version_rc.o $(__basedll___depname) $(__coredll___depname) $(__monodll___depname) $(foreach f,$(subst \,/,$(GLDLL_OBJECTS)),$(shell echo $f >> $(subst \,/,$@).rsp.tmp)) @move /y $@.rsp.tmp $@.rsp >nul - $(CXX) $(LINK_DLL_FLAGS) -fPIC -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--out-implib=$(LIBDIRNAME)\libwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.a $(____CAIRO_LIBDIR_FILENAMES) $(LDFLAGS) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme $(__WXLIBGLDEP_CORE_p) $(__WXLIBGLDEP_BASE_p) $(__WXLIB_MONO_p) -lopengl32 -lglu32 + $(CXX) $(LINK_DLL_FLAGS) -fPIC -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--out-implib=$(LIBDIRNAME)\libwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.a $(____CAIRO_LIBDIR_FILENAMES) $(LDFLAGS) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme $(__WXLIBGLDEP_CORE_p) $(__WXLIBGLDEP_BASE_p) $(__WXLIB_MONO_p) -lopengl32 @-del $@.rsp endif endif diff --git a/build/msw/makefile.vc b/build/msw/makefile.vc index 8bb1f4ebf5..32a5ef9cc4 100644 --- a/build/msw/makefile.vc +++ b/build/msw/makefile.vc @@ -6433,7 +6433,7 @@ wxstc: $(____wxstc_namedll_DEP) $(____wxstc_namelib_DEP) !if "$(SHARED)" == "1" && "$(USE_GUI)" == "1" && "$(USE_OPENGL)" == "1" $(LIBDIRNAME)\wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl$(WXCOMPILER)$(VENDORTAG).dll: $(OBJS)\gldll_dummy.obj $(GLDLL_OBJECTS) $(LIBDIRNAME)\wxexpat$(WXDEBUGFLAG).lib $(LIBDIRNAME)\wxzlib$(WXDEBUGFLAG).lib $(LIBDIRNAME)\wxregexu$(WXDEBUGFLAG).lib $(__wxtiff___depname) $(__wxjpeg___depname) $(__wxpng___depname) $(__wxscintilla) $(__wxlexilla) $(OBJS)\gldll_version.res $(__basedll___depname) $(__coredll___depname) $(__monodll___depname) link /DLL /NOLOGO /OUT:$@ $(__DEBUGINFO_6) /pdb:"$(LIBDIRNAME)\wx$(PORTNAME)$(WXUNIVNAME)$(WX_VERSION_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl$(WXCOMPILER)$(VENDORTAG).pdb" $(__DEBUGINFO_619) $(LINK_TARGET_CPU) /LIBPATH:$(LIBDIRNAME) $(____CAIRO_LIBDIR_FILENAMES) $(LDFLAGS) @<< - $(GLDLL_OBJECTS) $(GLDLL_RESOURCES) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib $(__WXLIBGLDEP_CORE_p) $(__WXLIBGLDEP_BASE_p) $(__WXLIB_MONO_p) opengl32.lib glu32.lib /IMPLIB:$(LIBDIRNAME)\wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib + $(GLDLL_OBJECTS) $(GLDLL_RESOURCES) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib $(__WXLIBGLDEP_CORE_p) $(__WXLIBGLDEP_BASE_p) $(__WXLIB_MONO_p) opengl32.lib /IMPLIB:$(LIBDIRNAME)\wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib << !endif diff --git a/build/msw/wx_gl.vcxproj b/build/msw/wx_gl.vcxproj index 004f7fe46b..4a96394fc8 100644 --- a/build/msw/wx_gl.vcxproj +++ b/build/msw/wx_gl.vcxproj @@ -306,7 +306,7 @@ %(AdditionalOptions) - wxtiff$(wxSuffixDebug).lib;wxjpeg$(wxSuffixDebug).lib;wxpng$(wxSuffixDebug).lib;wxzlib$(wxSuffixDebug).lib;wxregexu$(wxSuffixDebug).lib;wxexpat$(wxSuffixDebug).lib;$(wxToolkitLibNamePrefix)core.lib;$(wxBaseLibNamePrefix).lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + wxtiff$(wxSuffixDebug).lib;wxjpeg$(wxSuffixDebug).lib;wxpng$(wxSuffixDebug).lib;wxzlib$(wxSuffixDebug).lib;wxregexu$(wxSuffixDebug).lib;wxexpat$(wxSuffixDebug).lib;$(wxToolkitLibNamePrefix)core.lib;$(wxBaseLibNamePrefix).lib;opengl32.lib;%(AdditionalDependencies) $(OutDir)$(wxToolkitLibNamePrefix)$(ProjectName).lib true $(OutDir);%(AdditionalLibraryDirectories) @@ -347,7 +347,7 @@ %(AdditionalOptions) - wxtiff$(wxSuffixDebug).lib;wxjpeg$(wxSuffixDebug).lib;wxpng$(wxSuffixDebug).lib;wxzlib$(wxSuffixDebug).lib;wxregexu$(wxSuffixDebug).lib;wxexpat$(wxSuffixDebug).lib;$(wxToolkitLibNamePrefix)core.lib;$(wxBaseLibNamePrefix).lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + wxtiff$(wxSuffixDebug).lib;wxjpeg$(wxSuffixDebug).lib;wxpng$(wxSuffixDebug).lib;wxzlib$(wxSuffixDebug).lib;wxregexu$(wxSuffixDebug).lib;wxexpat$(wxSuffixDebug).lib;$(wxToolkitLibNamePrefix)core.lib;$(wxBaseLibNamePrefix).lib;opengl32.lib;%(AdditionalDependencies) $(OutDir)$(wxToolkitLibNamePrefix)$(ProjectName).lib true $(OutDir);%(AdditionalLibraryDirectories) @@ -388,7 +388,7 @@ %(AdditionalOptions) - wxtiff$(wxSuffixDebug).lib;wxjpeg$(wxSuffixDebug).lib;wxpng$(wxSuffixDebug).lib;wxzlib$(wxSuffixDebug).lib;wxregexu$(wxSuffixDebug).lib;wxexpat$(wxSuffixDebug).lib;$(wxToolkitLibNamePrefix)core.lib;$(wxBaseLibNamePrefix).lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + wxtiff$(wxSuffixDebug).lib;wxjpeg$(wxSuffixDebug).lib;wxpng$(wxSuffixDebug).lib;wxzlib$(wxSuffixDebug).lib;wxregexu$(wxSuffixDebug).lib;wxexpat$(wxSuffixDebug).lib;$(wxToolkitLibNamePrefix)core.lib;$(wxBaseLibNamePrefix).lib;opengl32.lib;%(AdditionalDependencies) $(OutDir)$(wxToolkitLibNamePrefix)$(ProjectName).lib true $(OutDir);%(AdditionalLibraryDirectories) @@ -432,7 +432,7 @@ %(AdditionalOptions) - wxtiff$(wxSuffixDebug).lib;wxjpeg$(wxSuffixDebug).lib;wxpng$(wxSuffixDebug).lib;wxzlib$(wxSuffixDebug).lib;wxregexu$(wxSuffixDebug).lib;wxexpat$(wxSuffixDebug).lib;$(wxToolkitLibNamePrefix)core.lib;$(wxBaseLibNamePrefix).lib;opengl32.lib;glu32.lib;%(AdditionalDependencies) + wxtiff$(wxSuffixDebug).lib;wxjpeg$(wxSuffixDebug).lib;wxpng$(wxSuffixDebug).lib;wxzlib$(wxSuffixDebug).lib;wxregexu$(wxSuffixDebug).lib;wxexpat$(wxSuffixDebug).lib;$(wxToolkitLibNamePrefix)core.lib;$(wxBaseLibNamePrefix).lib;opengl32.lib;%(AdditionalDependencies) $(OutDir)$(wxToolkitLibNamePrefix)$(ProjectName).lib true $(OutDir);%(AdditionalLibraryDirectories) @@ -494,4 +494,4 @@ - \ No newline at end of file + diff --git a/build/tools/before_install.sh b/build/tools/before_install.sh index 8c5de16fc5..3932c09673 100755 --- a/build/tools/before_install.sh +++ b/build/tools/before_install.sh @@ -95,7 +95,7 @@ case $(uname -s) in extra_deps="$extra_deps \ libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \ - libglu1-mesa-dev" + " esac # Install locales used by our tests to run all the tests instead of @@ -128,7 +128,7 @@ case $(uname -s) in fi if [ -f /etc/redhat-release ]; then - dnf install -y ${WX_EXTRA_PACKAGES} expat-devel findutils g++ git-core gspell-devel gstreamer1-plugins-base-devel gtk3-devel make libcurl-devel libGLU-devel libjpeg-devel libnotify-devel libpng-devel libSM-devel libsecret-devel libtiff-devel SDL-devel webkit2gtk4.1-devel zlib-devel + dnf install -y ${WX_EXTRA_PACKAGES} expat-devel findutils g++ git-core gspell-devel gstreamer1-plugins-base-devel gtk3-devel make libcurl-devel libjpeg-devel libnotify-devel libpng-devel libSM-devel libsecret-devel libtiff-devel SDL-devel webkit2gtk4.1-devel zlib-devel fi ;; diff --git a/configure b/configure index 30f90e8582..9fd73062eb 100755 --- a/configure +++ b/configure @@ -958,8 +958,6 @@ WAYLAND_EGL_LIBS WAYLAND_EGL_CFLAGS EGL_LIBS EGL_CFLAGS -GLU_LIBS -GLU_CFLAGS GL_LIBS GL_CFLAGS SM_LIBS @@ -1415,8 +1413,6 @@ SM_CFLAGS SM_LIBS GL_CFLAGS GL_LIBS -GLU_CFLAGS -GLU_LIBS EGL_CFLAGS EGL_LIBS WAYLAND_EGL_CFLAGS @@ -2450,8 +2446,6 @@ Some influential environment variables: SM_LIBS linker flags for SM, overriding pkg-config GL_CFLAGS C compiler flags for GL, overriding pkg-config GL_LIBS linker flags for GL, overriding pkg-config - GLU_CFLAGS C compiler flags for GLU, overriding pkg-config - GLU_LIBS linker flags for GLU, overriding pkg-config EGL_CFLAGS C compiler flags for EGL, overriding pkg-config EGL_LIBS linker flags for EGL, overriding pkg-config WAYLAND_EGL_CFLAGS @@ -30129,7 +30123,7 @@ if test "$wxUSE_OPENGL" = "yes" -o "$wxUSE_OPENGL" = "auto"; then if test "$wxUSE_OSX_COCOA" = 1; then OPENGL_LIBS="-framework OpenGL -framework AGL" elif test "$wxUSE_MSW" = 1; then - OPENGL_LIBS="-lopengl32 -lglu32" + OPENGL_LIBS="-lopengl32" elif test "$wxUSE_X11" = 1 -o "$wxUSE_GTK" = 1 -o "$wxUSE_QT" = 1; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for OpenGL headers" >&5 @@ -30170,10 +30164,6 @@ $as_echo "not found" >&6; } " if test "x$ac_cv_header_GL_gl_h" = xyes; then : - ac_fn_c_check_header_compile "$LINENO" "GL/glu.h" "ac_cv_header_GL_glu_h" " -" -if test "x$ac_cv_header_GL_glu_h" = xyes; then : - found_gl=0 @@ -30536,369 +30526,8 @@ fi fi fi - - ac_find_libraries= - - fl_pkgname=`echo "GLU" | tr [:upper:] [:lower:]` - - -if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. -set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -PKG_CONFIG=$ac_cv_path_PKG_CONFIG -if test -n "$PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 -$as_echo "$PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_path_PKG_CONFIG"; then - ac_pt_PKG_CONFIG=$PKG_CONFIG - # Extract the first word of "pkg-config", so it can be a program name with args. -set dummy pkg-config; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $ac_pt_PKG_CONFIG in - [\\/]* | ?:[\\/]*) - ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - - ;; -esac -fi -ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG -if test -n "$ac_pt_PKG_CONFIG"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 -$as_echo "$ac_pt_PKG_CONFIG" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_pt_PKG_CONFIG" = x; then - PKG_CONFIG="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - PKG_CONFIG=$ac_pt_PKG_CONFIG - fi -else - PKG_CONFIG="$ac_cv_path_PKG_CONFIG" -fi - -fi -if test -n "$PKG_CONFIG"; then - _pkg_min_version=0.9.0 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 -$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } - if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - PKG_CONFIG="" - fi - -fi 6> /dev/null - -pkg_failed=no -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GLU" >&5 -$as_echo_n "checking for GLU... " >&6; } - -if test -n "$PKG_CONFIG"; then - if test -n "$GLU_CFLAGS"; then - pkg_cv_GLU_CFLAGS="$GLU_CFLAGS" - else - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$fl_pkgname\""; } >&5 - ($PKG_CONFIG --exists --print-errors "$fl_pkgname") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_GLU_CFLAGS=`$PKG_CONFIG --cflags "$fl_pkgname" 2>/dev/null` -else - pkg_failed=yes -fi - fi -else - pkg_failed=untried -fi -if test -n "$PKG_CONFIG"; then - if test -n "$GLU_LIBS"; then - pkg_cv_GLU_LIBS="$GLU_LIBS" - else - if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$fl_pkgname\""; } >&5 - ($PKG_CONFIG --exists --print-errors "$fl_pkgname") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - pkg_cv_GLU_LIBS=`$PKG_CONFIG --libs "$fl_pkgname" 2>/dev/null` -else - pkg_failed=yes -fi - fi -else - pkg_failed=untried -fi - - - -if test $pkg_failed = yes; then - -if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then - _pkg_short_errors_supported=yes -else - _pkg_short_errors_supported=no -fi - if test $_pkg_short_errors_supported = yes; then - GLU_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$fl_pkgname"` - else - GLU_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$fl_pkgname"` - fi - # Put the nasty error message in config.log where it belongs - echo "$GLU_PKG_ERRORS" >&5 - - - if test "x$ac_find_libraries" = "x"; then - if test "xgluBeginCurve" != "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gluBeginCurve in -lGLU" >&5 -$as_echo_n "checking for gluBeginCurve in -lGLU... " >&6; } -if ${ac_cv_lib_GLU_gluBeginCurve+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lGLU $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gluBeginCurve (); -int -main () -{ -return gluBeginCurve (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_GLU_gluBeginCurve=yes -else - ac_cv_lib_GLU_gluBeginCurve=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GLU_gluBeginCurve" >&5 -$as_echo "$ac_cv_lib_GLU_gluBeginCurve" >&6; } -if test "x$ac_cv_lib_GLU_gluBeginCurve" = xyes; then : - ac_find_libraries="std" -fi - - fi - fi - - if test "x$ac_find_libraries" = "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking elsewhere" >&5 -$as_echo_n "checking elsewhere... " >&6; } - - ac_find_libraries= - for ac_dir in /opt/graphics/OpenGL/lib $SEARCH_LIB - do - for ac_extension in a so sl dylib dll.a; do - if test -f "$ac_dir/libGLU.$ac_extension"; then - ac_find_libraries=$ac_dir - break 2 - fi - done - done - - if test "x$ac_find_libraries" != "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - fi - -elif test $pkg_failed = untried; then - - if test "x$ac_find_libraries" = "x"; then - if test "xgluBeginCurve" != "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gluBeginCurve in -lGLU" >&5 -$as_echo_n "checking for gluBeginCurve in -lGLU... " >&6; } -if ${ac_cv_lib_GLU_gluBeginCurve+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lGLU $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char gluBeginCurve (); -int -main () -{ -return gluBeginCurve (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_GLU_gluBeginCurve=yes -else - ac_cv_lib_GLU_gluBeginCurve=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_GLU_gluBeginCurve" >&5 -$as_echo "$ac_cv_lib_GLU_gluBeginCurve" >&6; } -if test "x$ac_cv_lib_GLU_gluBeginCurve" = xyes; then : - ac_find_libraries="std" -fi - - fi - fi - - if test "x$ac_find_libraries" = "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking elsewhere" >&5 -$as_echo_n "checking elsewhere... " >&6; } - - ac_find_libraries= - for ac_dir in /opt/graphics/OpenGL/lib $SEARCH_LIB - do - for ac_extension in a so sl dylib dll.a; do - if test -f "$ac_dir/libGLU.$ac_extension"; then - ac_find_libraries=$ac_dir - break 2 - fi - done - done - - if test "x$ac_find_libraries" != "x"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - fi - -else - GLU_CFLAGS=$pkg_cv_GLU_CFLAGS - GLU_LIBS=$pkg_cv_GLU_LIBS - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - - ac_find_libraries="std" - - eval ac_find_cflags=\$GLU_CFLAGS - eval fl_libs=\$GLU_LIBS - - for fl_path in $fl_libs - do - if test `echo "$fl_path" | cut -c 1-2` = "-L"; then - ac_find_libraries=`echo "$fl_path" | cut -c 3-` - fi - done - -fi - - if test "$ac_find_libraries" != "" ; then - if test "$ac_find_libraries" != "std" ; then - - if test "$ac_find_libraries" = "default location"; then - ac_path_to_link="" - else - echo "$LDFLAGS" | grep "\-L$ac_find_libraries" > /dev/null - result=$? - if test $result = 0; then - ac_path_to_link="" - else - ac_path_to_link=" -L$ac_find_libraries" - fi - fi - - if test "$ac_path_to_link" != " -L/usr/lib" -a \ - "$ac_path_to_link" != "$LDFLAGS_GL" ; then - LDFLAGS_GL="$LDFLAGS_GL $ac_path_to_link" - fi - fi - found_gl=1 - OPENGL_LIBS="-lGL -lGLU" + OPENGL_LIBS="-lGL" if test "$WXGTK3" = 1; then if test "$wxUSE_GLCANVAS_EGL" != "no"; then @@ -31065,7 +30694,6 @@ $as_echo "$as_me: wxGLCanvas will not have Wayland support" >&6;} fi fi fi - fi fi if test "$found_gl" != 1; then @@ -31428,7 +31056,7 @@ fi LDFLAGS_GL="$LDFLAGS_GL $ac_path_to_link" fi fi - OPENGL_LIBS="-lMesaGL -lMesaGLU" + OPENGL_LIBS="-lMesaGL" fi fi @@ -31436,10 +31064,6 @@ fi -fi - - - if test "x$OPENGL_LIBS" = "x"; then if test "$wxUSE_OPENGL" = "yes"; then as_fn_error $? "OpenGL libraries not available" "$LINENO" 5 diff --git a/configure.ac b/configure.ac index d8919d3cc9..6063333767 100644 --- a/configure.ac +++ b/configure.ac @@ -3285,7 +3285,7 @@ if test "$wxUSE_OPENGL" = "yes" -o "$wxUSE_OPENGL" = "auto"; then if test "$wxUSE_OSX_COCOA" = 1; then OPENGL_LIBS="-framework OpenGL -framework AGL" elif test "$wxUSE_MSW" = 1; then - OPENGL_LIBS="-lopengl32 -lglu32" + OPENGL_LIBS="-lopengl32" elif test "$wxUSE_X11" = 1 -o "$wxUSE_GTK" = 1 -o "$wxUSE_QT" = 1; then dnl adjust CPPFLAGS to include GL/gl.h location if necessary @@ -3301,7 +3301,6 @@ if test "$wxUSE_OPENGL" = "yes" -o "$wxUSE_OPENGL" = "auto"; then fi AC_CHECK_HEADER(GL/gl.h, [ - AC_CHECK_HEADER(GL/glu.h, [ found_gl=0 WX_FIND_LIB(GL, glBegin, [/opt/graphics/OpenGL/lib]) @@ -3313,21 +3312,8 @@ if test "$wxUSE_OPENGL" = "yes" -o "$wxUSE_OPENGL" = "auto"; then fi fi - dnl don't suppose that libGL and libGLU are always in the - dnl same directory -- this is not true for some common - dnl distributions - WX_FIND_LIB(GLU, gluBeginCurve, [/opt/graphics/OpenGL/lib]) - if test "$ac_find_libraries" != "" ; then - if test "$ac_find_libraries" != "std" ; then - WX_LINK_PATH_EXIST([$ac_find_libraries],[$LDFLAGS]) - if test "$ac_path_to_link" != " -L/usr/lib" -a \ - "$ac_path_to_link" != "$LDFLAGS_GL" ; then - LDFLAGS_GL="$LDFLAGS_GL $ac_path_to_link" - fi - fi - found_gl=1 - OPENGL_LIBS="-lGL -lGLU" + OPENGL_LIBS="-lGL" if test "$WXGTK3" = 1; then if test "$wxUSE_GLCANVAS_EGL" != "no"; then @@ -3354,7 +3340,6 @@ if test "$wxUSE_OPENGL" = "yes" -o "$wxUSE_OPENGL" = "auto"; then fi fi fi - fi fi if test "$found_gl" != 1; then @@ -3366,10 +3351,9 @@ if test "$wxUSE_OPENGL" = "yes" -o "$wxUSE_OPENGL" = "auto"; then LDFLAGS_GL="$LDFLAGS_GL $ac_path_to_link" fi fi - OPENGL_LIBS="-lMesaGL -lMesaGLU" + OPENGL_LIBS="-lMesaGL" fi fi - ],, [ ]) ], [], [ ]) diff --git a/docs/gtk/install.md b/docs/gtk/install.md index 4e96a10591..9fd1d73200 100644 --- a/docs/gtk/install.md +++ b/docs/gtk/install.md @@ -47,8 +47,8 @@ Debian and Debian-based distribution these libraries are part of `libgtk-3-dev` package, while in Fedora and other RPM-based distributions the same package is known as `gtk3-devel`. -For OpenGL support, you need `libgl1-mesa-dev` and `libglu1-mesa-dev` packages -under Debian and `mesa-libGL-devel` and `mesa-libGLU-devel` under Fedora. For +For OpenGL support, you need `libgl1-mesa-dev` packages +under Debian and `mesa-libGL-devel` and under Fedora. For EGL support, `libegl1-mesa-dev` or `mesa-libEGL-devel` is needed. wxMediaCtrl implementation requires GStreamer and its plugins development diff --git a/include/wx/android/setup.h b/include/wx/android/setup.h index 5129e7c41a..2bd971a541 100644 --- a/include/wx/android/setup.h +++ b/include/wx/android/setup.h @@ -1327,7 +1327,7 @@ // Setting wxUSE_GLCANVAS to 1 enables OpenGL support. You need to have OpenGL // headers and libraries to be able to compile the library with wxUSE_GLCANVAS -// set to 1 and, under Windows, also to add opengl32.lib and glu32.lib to the +// set to 1 and, under Windows, also to add opengl32.lib to the // list of libraries used to link your application when linking to wxWidgets // statically (although this is done implicitly for Microsoft Visual C++ users). // diff --git a/include/wx/gtk/setup.h b/include/wx/gtk/setup.h index 961903ab4f..07fbc7b4e4 100644 --- a/include/wx/gtk/setup.h +++ b/include/wx/gtk/setup.h @@ -1327,7 +1327,7 @@ // Setting wxUSE_GLCANVAS to 1 enables OpenGL support. You need to have OpenGL // headers and libraries to be able to compile the library with wxUSE_GLCANVAS -// set to 1 and, under Windows, also to add opengl32.lib and glu32.lib to the +// set to 1 and, under Windows, also to add opengl32.lib to the // list of libraries used to link your application when linking to wxWidgets // statically (although this is done implicitly for Microsoft Visual C++ users). // diff --git a/include/wx/msw/setup.h b/include/wx/msw/setup.h index 1856d472f1..51679db1ef 100644 --- a/include/wx/msw/setup.h +++ b/include/wx/msw/setup.h @@ -1327,7 +1327,7 @@ // Setting wxUSE_GLCANVAS to 1 enables OpenGL support. You need to have OpenGL // headers and libraries to be able to compile the library with wxUSE_GLCANVAS -// set to 1 and, under Windows, also to add opengl32.lib and glu32.lib to the +// set to 1 and, under Windows, also to add opengl32.lib to the // list of libraries used to link your application when linking to wxWidgets // statically (although this is done implicitly for Microsoft Visual C++ users). // diff --git a/include/wx/osx/setup.h b/include/wx/osx/setup.h index 22c23284b2..fe2f2f6ead 100644 --- a/include/wx/osx/setup.h +++ b/include/wx/osx/setup.h @@ -1334,7 +1334,7 @@ // Setting wxUSE_GLCANVAS to 1 enables OpenGL support. You need to have OpenGL // headers and libraries to be able to compile the library with wxUSE_GLCANVAS -// set to 1 and, under Windows, also to add opengl32.lib and glu32.lib to the +// set to 1 and, under Windows, also to add opengl32.lib to the // list of libraries used to link your application when linking to wxWidgets // statically (although this is done implicitly for Microsoft Visual C++ users). // diff --git a/include/wx/univ/setup.h b/include/wx/univ/setup.h index a75f6b06ae..6d3ffa8723 100644 --- a/include/wx/univ/setup.h +++ b/include/wx/univ/setup.h @@ -1327,7 +1327,7 @@ // Setting wxUSE_GLCANVAS to 1 enables OpenGL support. You need to have OpenGL // headers and libraries to be able to compile the library with wxUSE_GLCANVAS -// set to 1 and, under Windows, also to add opengl32.lib and glu32.lib to the +// set to 1 and, under Windows, also to add opengl32.lib to the // list of libraries used to link your application when linking to wxWidgets // statically (although this is done implicitly for Microsoft Visual C++ users). // diff --git a/interface/wx/glcanvas.h b/interface/wx/glcanvas.h index 20e55b3763..a86edb97bf 100644 --- a/interface/wx/glcanvas.h +++ b/interface/wx/glcanvas.h @@ -774,8 +774,8 @@ enum libraries are found. On Windows, OpenGL support is enabled by default (@c wxUSE_GLCANVAS set to @c 1 in the @c setup.h file). If your program links with wxWidgets - statically, you need to add @c opengl32.lib (and @c glu32.lib for old - OpenGL versions) to the list of the libraries your program is linked with. + statically, you need to add @c opengl32.lib to the list of libraries + your program is linked with. @library{wxgl} @category{gl} diff --git a/samples/opengl/cube/makefile.gcc b/samples/opengl/cube/makefile.gcc index fa4d106a46..bd35bec151 100644 --- a/samples/opengl/cube/makefile.gcc +++ b/samples/opengl/cube/makefile.gcc @@ -211,7 +211,7 @@ ifeq ($(USE_OPENGL),1) $(OBJS)\cube.exe: $(CUBE_OBJECTS) $(OBJS)\cube_sample_rc.o $(foreach f,$(subst \,/,$(CUBE_OBJECTS)),$(shell echo $f >> $(subst \,/,$@).rsp.tmp)) @move /y $@.rsp.tmp $@.rsp >nul - $(CXX) -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) -lwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl -lopengl32 -lglu32 $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme + $(CXX) -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) -lwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl -lopengl32 $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme @-del $@.rsp endif diff --git a/samples/opengl/cube/makefile.vc b/samples/opengl/cube/makefile.vc index 98cb4a2ad5..298a88c09a 100644 --- a/samples/opengl/cube/makefile.vc +++ b/samples/opengl/cube/makefile.vc @@ -419,7 +419,7 @@ clean: !if "$(USE_OPENGL)" == "1" $(OBJS)\cube.exe: $(CUBE_OBJECTS) $(OBJS)\cube_sample.res link /NOLOGO /OUT:$@ $(__DEBUGINFO_1) /pdb:"$(OBJS)\cube.pdb" $(__DEBUGINFO_2) $(LINK_TARGET_CPU) /LIBPATH:$(LIBDIRNAME) $(WIN32_DPI_LINKFLAG) /SUBSYSTEM:WINDOWS $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) @<< - $(CUBE_OBJECTS) $(CUBE_RESOURCES) wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib opengl32.lib glu32.lib $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib + $(CUBE_OBJECTS) $(CUBE_RESOURCES) wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib opengl32.lib $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib << !endif diff --git a/samples/opengl/isosurf/isosurf.h b/samples/opengl/isosurf/isosurf.h index 659b19c3c1..043741fad5 100644 --- a/samples/opengl/isosurf/isosurf.h +++ b/samples/opengl/isosurf/isosurf.h @@ -15,14 +15,11 @@ #if defined(__WXMAC__) # ifdef __DARWIN__ # include -# include # else # include -# include # endif #else # include -# include #endif // the maximum number of vertex in the loaded .dat file diff --git a/samples/opengl/isosurf/makefile.gcc b/samples/opengl/isosurf/makefile.gcc index 37d7b1d431..d076e18f64 100644 --- a/samples/opengl/isosurf/makefile.gcc +++ b/samples/opengl/isosurf/makefile.gcc @@ -211,7 +211,7 @@ ifeq ($(USE_OPENGL),1) $(OBJS)\isosurf.exe: $(ISOSURF_OBJECTS) $(OBJS)\isosurf_sample_rc.o $(foreach f,$(subst \,/,$(ISOSURF_OBJECTS)),$(shell echo $f >> $(subst \,/,$@).rsp.tmp)) @move /y $@.rsp.tmp $@.rsp >nul - $(CXX) -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) -lwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl -lopengl32 -lglu32 $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme + $(CXX) -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) -lwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl -lopengl32 $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme @-del $@.rsp endif diff --git a/samples/opengl/isosurf/makefile.vc b/samples/opengl/isosurf/makefile.vc index 97a19a2d96..1f5b1b6a2e 100644 --- a/samples/opengl/isosurf/makefile.vc +++ b/samples/opengl/isosurf/makefile.vc @@ -419,7 +419,7 @@ clean: !if "$(USE_OPENGL)" == "1" $(OBJS)\isosurf.exe: $(ISOSURF_OBJECTS) $(OBJS)\isosurf_sample.res link /NOLOGO /OUT:$@ $(__DEBUGINFO_1) /pdb:"$(OBJS)\isosurf.pdb" $(__DEBUGINFO_2) $(LINK_TARGET_CPU) /LIBPATH:$(LIBDIRNAME) $(WIN32_DPI_LINKFLAG) /SUBSYSTEM:WINDOWS $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) @<< - $(ISOSURF_OBJECTS) $(ISOSURF_RESOURCES) wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib opengl32.lib glu32.lib $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib + $(ISOSURF_OBJECTS) $(ISOSURF_RESOURCES) wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib opengl32.lib $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib << !endif diff --git a/samples/opengl/penguin/Makefile.in b/samples/opengl/penguin/Makefile.in index 60c3c1c1ad..a4237ee540 100644 --- a/samples/opengl/penguin/Makefile.in +++ b/samples/opengl/penguin/Makefile.in @@ -169,7 +169,7 @@ distclean: clean rm -f config.cache config.log config.status bk-deps bk-make-pch Makefile @COND_USE_OPENGL_1@penguin$(EXEEXT): $(PENGUIN_OBJECTS) $(__penguin___win32rc) -@COND_USE_OPENGL_1@ $(CXX) -o $@ $(PENGUIN_OBJECTS) -L$(LIBDIRNAME) $(LDFLAGS_GUI) $(SAMPLES_RPATH_FLAG) $(LDFLAGS) $(WX_LDFLAGS) -lwx_$(PORTNAME)$(WXUNIVNAME)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl-$(WX_RELEASE)$(HOST_SUFFIX) $(EXTRALIBS_OPENGL) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) $(EXTRALIBS_FOR_GUI) $(__LIB_ZLIB_p) $(__LIB_REGEX_p) $(__LIB_EXPAT_p) $(EXTRALIBS_FOR_BASE) $(LIBS) +@COND_USE_OPENGL_1@ $(CXX) -o $@ $(PENGUIN_OBJECTS) -L$(LIBDIRNAME) $(LDFLAGS_GUI) $(SAMPLES_RPATH_FLAG) $(LDFLAGS) $(WX_LDFLAGS) -lwx_$(PORTNAME)$(WXUNIVNAME)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl-$(WX_RELEASE)$(HOST_SUFFIX) $(EXTRALIBS_OPENGL) $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) $(EXTRALIBS_FOR_GUI) $(__LIB_ZLIB_p) $(__LIB_REGEX_p) $(__LIB_EXPAT_p) $(EXTRALIBS_FOR_BASE) $(LIBS) @COND_USE_OPENGL_1@ $(__penguin___os2_emxbindcmd) @COND_PLATFORM_MACOSX_1_USE_OPENGL_1@penguin.app/Contents/PkgInfo: $(__penguin___depname) $(top_srcdir)/src/osx/carbon/Info.plist.in $(top_srcdir)/src/osx/carbon/wxmac.icns diff --git a/samples/opengl/penguin/dxfrenderer.cpp b/samples/opengl/penguin/dxfrenderer.cpp index 8b29f6f0ff..a81f7f4d5b 100644 --- a/samples/opengl/penguin/dxfrenderer.cpp +++ b/samples/opengl/penguin/dxfrenderer.cpp @@ -17,17 +17,12 @@ #include "wx/wfstream.h" #include "wx/txtstrm.h" +#include "wx/glcanvas.h" #if !wxUSE_GLCANVAS #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library" #endif -#ifdef __DARWIN__ - #include -#else - #include -#endif - #include #include "dxfrenderer.h" diff --git a/samples/opengl/penguin/makefile.gcc b/samples/opengl/penguin/makefile.gcc index c482329c10..9911c206fa 100644 --- a/samples/opengl/penguin/makefile.gcc +++ b/samples/opengl/penguin/makefile.gcc @@ -218,7 +218,7 @@ ifeq ($(USE_OPENGL),1) $(OBJS)\penguin.exe: $(PENGUIN_OBJECTS) $(OBJS)\penguin_sample_rc.o $(foreach f,$(subst \,/,$(PENGUIN_OBJECTS)),$(shell echo $f >> $(subst \,/,$@).rsp.tmp)) @move /y $@.rsp.tmp $@.rsp >nul - $(CXX) -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) -lwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl -lopengl32 -lglu32 $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme + $(CXX) -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) -lwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl -lopengl32 $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme @-del $@.rsp endif diff --git a/samples/opengl/penguin/makefile.unx b/samples/opengl/penguin/makefile.unx index 5244e9960a..7f36d867f4 100644 --- a/samples/opengl/penguin/makefile.unx +++ b/samples/opengl/penguin/makefile.unx @@ -98,7 +98,7 @@ test_for_selected_wxbuild: @$(WX_CONFIG) $(WX_CONFIG_FLAGS) penguin: $(PENGUIN_OBJECTS) - $(CXX) -o $@ $(PENGUIN_OBJECTS) $(LDFLAGS) `$(WX_CONFIG) $(WX_CONFIG_FLAGS) --libs gl,core,base` -lGL -lGLU + $(CXX) -o $@ $(PENGUIN_OBJECTS) $(LDFLAGS) `$(WX_CONFIG) $(WX_CONFIG_FLAGS) --libs gl,core,base` -lGL penguin_penguin.o: ./penguin.cpp $(CXX) -c -o $@ $(PENGUIN_CXXFLAGS) $(CPPDEPS) $< diff --git a/samples/opengl/penguin/makefile.vc b/samples/opengl/penguin/makefile.vc index 215c70b202..e003c3c841 100644 --- a/samples/opengl/penguin/makefile.vc +++ b/samples/opengl/penguin/makefile.vc @@ -431,7 +431,7 @@ clean: !if "$(USE_OPENGL)" == "1" $(OBJS)\penguin.exe: $(PENGUIN_OBJECTS) $(OBJS)\penguin_sample.res link /NOLOGO /OUT:$@ $(__DEBUGINFO_1) /pdb:"$(OBJS)\penguin.pdb" $(__DEBUGINFO_2) $(LINK_TARGET_CPU) /LIBPATH:$(LIBDIRNAME) $(WIN32_DPI_LINKFLAG) /SUBSYSTEM:WINDOWS $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) @<< - $(PENGUIN_OBJECTS) $(PENGUIN_RESOURCES) wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib opengl32.lib glu32.lib $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib + $(PENGUIN_OBJECTS) $(PENGUIN_RESOURCES) wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib opengl32.lib $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib << !endif diff --git a/samples/opengl/penguin/penguin.bkl b/samples/opengl/penguin/penguin.bkl index a7283caa6a..e11dc2e545 100644 --- a/samples/opengl/penguin/penguin.bkl +++ b/samples/opengl/penguin/penguin.bkl @@ -8,13 +8,10 @@ 1 - + GL - - GLU - @@ -31,7 +28,6 @@ core base $(SYS_GL_LIB) - $(SYS_GLU_LIB) diff --git a/samples/opengl/penguin/penguin.cpp b/samples/opengl/penguin/penguin.cpp index a2b5da28e4..898e377c4e 100644 --- a/samples/opengl/penguin/penguin.cpp +++ b/samples/opengl/penguin/penguin.cpp @@ -21,11 +21,6 @@ #endif #include "penguin.h" -#ifdef __DARWIN__ - #include -#else - #include -#endif #include "../../sample.xpm" @@ -312,7 +307,9 @@ void TestGLCanvas::ResetProjectionMode() glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(45, double(ClientSize.x) / ClientSize.y, 1, 100); + double fH = tan(M_PI / 8); + double fW = fH * ClientSize.x / ClientSize.y; + glFrustum(-fW, fW, -fH, fH, 1.0, 100.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } diff --git a/samples/opengl/pyramid/makefile.gcc b/samples/opengl/pyramid/makefile.gcc index fb68628929..9348bf3847 100644 --- a/samples/opengl/pyramid/makefile.gcc +++ b/samples/opengl/pyramid/makefile.gcc @@ -214,7 +214,7 @@ ifeq ($(USE_OPENGL),1) $(OBJS)\pyramid.exe: $(PYRAMID_OBJECTS) $(OBJS)\pyramid_sample_rc.o $(foreach f,$(subst \,/,$(PYRAMID_OBJECTS)),$(shell echo $f >> $(subst \,/,$@).rsp.tmp)) @move /y $@.rsp.tmp $@.rsp >nul - $(CXX) -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) -lwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl -lopengl32 -lglu32 $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme + $(CXX) -o $@ @$@.rsp $(__DEBUGINFO) $(__THREADSFLAG) -L$(LIBDIRNAME) -Wl,--subsystem,windows -mwindows $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) -lwx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl -lopengl32 $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) -lwxzlib$(WXDEBUGFLAG) -lwxregexu$(WXDEBUGFLAG) -lwxexpat$(WXDEBUGFLAG) $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lws2_32 -lwininet -loleacc -luxtheme @-del $@.rsp endif diff --git a/samples/opengl/pyramid/makefile.vc b/samples/opengl/pyramid/makefile.vc index fed9a54f8b..58613988f6 100644 --- a/samples/opengl/pyramid/makefile.vc +++ b/samples/opengl/pyramid/makefile.vc @@ -422,7 +422,7 @@ clean: !if "$(USE_OPENGL)" == "1" $(OBJS)\pyramid.exe: $(PYRAMID_OBJECTS) $(OBJS)\pyramid_sample.res link /NOLOGO /OUT:$@ $(__DEBUGINFO_1) /pdb:"$(OBJS)\pyramid.pdb" $(__DEBUGINFO_2) $(LINK_TARGET_CPU) /LIBPATH:$(LIBDIRNAME) $(WIN32_DPI_LINKFLAG) /SUBSYSTEM:WINDOWS $(____CAIRO_LIBDIR_FILENAMES_p) $(LDFLAGS) @<< - $(PYRAMID_OBJECTS) $(PYRAMID_RESOURCES) wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib opengl32.lib glu32.lib $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib + $(PYRAMID_OBJECTS) $(PYRAMID_RESOURCES) wx$(PORTNAME)$(WXUNIVNAME)$(WX_RELEASE_NODOT)u$(WXDEBUGFLAG)$(WX_LIB_FLAVOUR)_gl.lib opengl32.lib $(__WXLIB_CORE_p) $(__WXLIB_BASE_p) $(__WXLIB_MONO_p) $(__LIB_SCINTILLA_IF_MONO_p) $(__LIB_LEXILLA_IF_MONO_p) $(__LIB_TIFF_p) $(__LIB_JPEG_p) $(__LIB_PNG_p) wxzlib$(WXDEBUGFLAG).lib wxregexu$(WXDEBUGFLAG).lib wxexpat$(WXDEBUGFLAG).lib $(EXTRALIBS_FOR_BASE) $(__CAIRO_LIB_p) kernel32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib winmm.lib shell32.lib shlwapi.lib comctl32.lib ole32.lib oleaut32.lib uuid.lib rpcrt4.lib advapi32.lib version.lib ws2_32.lib wininet.lib << !endif diff --git a/src/msw/glcanvas.cpp b/src/msw/glcanvas.cpp index 21e0b5ea45..96d49c8228 100644 --- a/src/msw/glcanvas.cpp +++ b/src/msw/glcanvas.cpp @@ -170,7 +170,6 @@ inline T wxWGLProcCast(PROC proc) // compilers (e.g. MinGW) this needs to be done at makefiles level. #ifdef _MSC_VER # pragma comment( lib, "opengl32" ) -# pragma comment( lib, "glu32" ) #endif //----------------------------------------------------------------------------- From 00dff6e3bce72cc444c0602e13cf346a3340746b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 27 Dec 2023 16:08:37 +0100 Subject: [PATCH 157/257] Stop using $EGREP in configure.ac unnecessarily We don't have DISABLED_UTILS or DISABLED_DEMOS variables, so it's useless to exclude them from the makefiles list -- just stop doing it. This fixes a problem with using EGREP without preceding AC_PROG_EGREP with autoconf 2.72, as EGREP is not defined any longer with this version. See #24168. --- configure | 5 +---- configure.ac | 7 +------ 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/configure b/configure index 9fd73062eb..310adf5aa9 100755 --- a/configure +++ b/configure @@ -42983,10 +42983,7 @@ for subdir in $SUBDIRS; do makefiles="samples/$subtree/Makefile.in $makefiles" done else - disabled_var=DISABLED_`echo $subdir | tr '[a-z]' '[A-Z]'` - eval "disabled=\$$disabled_var" - disabled=/`echo X $disabled | sed 's@ @/|/@g'`/ - makefiles=`(cd $srcdir ; find $subdir -name Makefile.in) | $EGREP -v "$disabled"` + makefiles=`(cd $srcdir ; find $subdir -name Makefile.in)` fi else if test ${subdir} = "samples"; then diff --git a/configure.ac b/configure.ac index 6063333767..c608f9f4cf 100644 --- a/configure.ac +++ b/configure.ac @@ -8048,12 +8048,7 @@ for subdir in $SUBDIRS; do done else dnl assume that everything compiles for utils &c - dnl any that shouldn't be built can be added to - dnl DISABLED_UTILS, DISABLED_DEMOS - disabled_var=DISABLED_`echo $subdir | tr '[[a-z]]' '[[A-Z]]'` - eval "disabled=\$$disabled_var" - disabled=/`echo X $disabled | sed 's@ @/|/@g'`/ - makefiles=`(cd $srcdir ; find $subdir -name Makefile.in) | $EGREP -v "$disabled"` + makefiles=`(cd $srcdir ; find $subdir -name Makefile.in)` fi else dnl we build wxBase only From 7543e49c3c36ca45df1af4de309b04db2746ebaa Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 30 Dec 2023 17:01:19 +0100 Subject: [PATCH 158/257] Add support for %F (ISO 8601 date) format specifier to wxDateTime Recognize it when formatting and parsing dates. Closes #24173. --- src/common/datetimefmt.cpp | 20 ++++++++++++++++++++ tests/datetime/datetimetest.cpp | 1 + 2 files changed, 21 insertions(+) diff --git a/src/common/datetimefmt.cpp b/src/common/datetimefmt.cpp index ff72517769..cc2061a175 100644 --- a/src/common/datetimefmt.cpp +++ b/src/common/datetimefmt.cpp @@ -580,6 +580,10 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const res += wxString::Format(fmt, tm.mday); break; + case wxT('F'): // ISO 8601 date + res += wxString::Format(wxT("%04d-%02d-%02d"), tm.year, tm.mon + 1, tm.mday); + break; + case wxT('g'): // 2-digit week-based year res += wxString::Format(fmt, GetWeekBasedYear() % 100); break; @@ -1229,6 +1233,22 @@ wxDateTime::ParseFormat(const wxString& date, mday = (wxDateTime_t)num; break; + case wxT('F'): // ISO 8601 date + { + wxDateTime dt = ParseFormatAt(input, end, wxS("%Y-%m-%d")); + if ( !dt.IsValid() ) + return false; + + const Tm tm = dt.GetTm(); + + year = tm.year; + mon = tm.mon; + mday = tm.mday; + + haveDay = haveMon = haveYear = true; + } + break; + case wxT('H'): // hour in 24h format (00-23) if ( !GetNumericToken(width, input, end, &num) || (num > 23) ) { diff --git a/tests/datetime/datetimetest.cpp b/tests/datetime/datetimetest.cpp index 43c3d94cf3..565a1077cf 100644 --- a/tests/datetime/datetimetest.cpp +++ b/tests/datetime/datetimetest.cpp @@ -684,6 +684,7 @@ void DateTimeTestCase::TestTimeFormat() { CompareYear, "Date is %x, time is %X" }, // %x could use 2 digits { CompareTime, "Time is %H:%M:%S or %I:%M:%S %p" }, { CompareNone, "The day of year: %j, the week of year: %W" }, + { CompareDate, "ISO date using short form: %F" }, { CompareDate, "ISO date without separators: %Y%m%d" }, { CompareBoth, "RFC 2822 string: %Y-%m-%d %H:%M:%S.%l %z" }, From d31305beebc3f78824129ce57ee97f3d28a13409 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 31 Dec 2023 15:26:44 +0100 Subject: [PATCH 159/257] Do use POSIX strftime() specifiers under Windows with MSVS All currently supported versions of MSVS support POSIX "%g", "%G", "%V" and "%z" format specifiers, so do call strftime() even if they are used in the format string. However don't do this when using MinGW, as its CRT still doesn't support them. --- src/common/datetimefmt.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/common/datetimefmt.cpp b/src/common/datetimefmt.cpp index cc2061a175..21cd4f4a5e 100644 --- a/src/common/datetimefmt.cpp +++ b/src/common/datetimefmt.cpp @@ -337,8 +337,8 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const bool isPercent = false; // We also can't use strftime() if we use non standard specifier: either - // our own extension "%l" or one of "%g", "%G", "%V", "%z" which are POSIX - // but not supported under Windows. + // our own extension "%l" or one of POSIX specifiers not supported when + // using MinGW, see https://sourceforge.net/p/mingw-w64/bugs/793/ for ( wxString::const_iterator p = format.begin(); canUseStrftime && p != format.end(); ++p ) @@ -354,12 +354,12 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const switch ( (*p).GetValue() ) { case 'l': -#ifdef __WINDOWS__ +#ifdef __MINGW32__ case 'g': case 'G': case 'V': case 'z': -#endif // __WINDOWS__ +#endif // __MINGW32__ canUseStrftime = false; break; } From dd76ab3e6703df0e1657e70b46775f60d3761742 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 31 Dec 2023 15:29:19 +0100 Subject: [PATCH 160/257] Avoid calling strftime("%F") when using MinGW This format specifier is not supported by its CRT. --- src/common/datetimefmt.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/common/datetimefmt.cpp b/src/common/datetimefmt.cpp index 21cd4f4a5e..dd2b47c60c 100644 --- a/src/common/datetimefmt.cpp +++ b/src/common/datetimefmt.cpp @@ -337,7 +337,7 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const bool isPercent = false; // We also can't use strftime() if we use non standard specifier: either - // our own extension "%l" or one of POSIX specifiers not supported when + // our own extension "%l" or one of C99/POSIX specifiers not supported when // using MinGW, see https://sourceforge.net/p/mingw-w64/bugs/793/ for ( wxString::const_iterator p = format.begin(); canUseStrftime && p != format.end(); @@ -355,6 +355,7 @@ wxString wxDateTime::Format(const wxString& formatp, const TimeZone& tz) const { case 'l': #ifdef __MINGW32__ + case 'F': case 'g': case 'G': case 'V': From 6ee9056c16ea30cfc3b4592b17a093472a3da6c5 Mon Sep 17 00:00:00 2001 From: Martin Corino Date: Fri, 29 Dec 2023 10:59:39 +0100 Subject: [PATCH 161/257] Fix column reordering in wxHeaderCtrlSimple and related problems Override required functions in wxHeaderCtrlSimple to avoid asserts if its columns are reordered. Also bring the code behaviour in agreement with the documentation by calling UpdateColumn() after calling UpdateColumnVisibility(). Finally, only call UpdateColumnsOrder() if the corresponding event was not processed as the application should use one xor the other mechanism for reacting to columns reordering, but not both. Closes #24108. Closes #24172. --- include/wx/headerctrl.h | 3 +++ interface/wx/headerctrl.h | 14 ++++++++------ src/common/headerctrlcmn.cpp | 14 ++++++++++++++ src/generic/headerctrlg.cpp | 17 ++++++++++++++++- src/msw/headerctrl.cpp | 12 +++++++++++- 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/include/wx/headerctrl.h b/include/wx/headerctrl.h index b13abd9052..31b4d66edf 100644 --- a/include/wx/headerctrl.h +++ b/include/wx/headerctrl.h @@ -343,6 +343,9 @@ protected: virtual const wxHeaderColumn& GetColumn(unsigned int idx) const override; virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle) override; + virtual void UpdateColumnVisibility(unsigned int idx, bool show) override; + virtual void UpdateColumnsOrder(const wxArrayInt& order) override; + // and define another one to be overridden in the derived classes: it // should return the best width for the given column contents or -1 if not // implemented, we use it to implement UpdateColumnWidthToFit() diff --git a/interface/wx/headerctrl.h b/interface/wx/headerctrl.h index 3980a9a01e..b5e0987e7f 100644 --- a/interface/wx/headerctrl.h +++ b/interface/wx/headerctrl.h @@ -447,13 +447,15 @@ protected: /** Method called when the columns order is changed in the customization - dialog. + dialog @em or when the EVT_HEADER_END_REORDER event is not handled after + dragging a single column. - This method is only called from ShowCustomizeDialog() when the user - changes the order of columns. In particular it is @em not called if a - single column changes place because the user dragged it to the new - location, the EVT_HEADER_END_REORDER event handler should be used to - react to this. + This method is always called from ShowCustomizeDialog() when the user + changes the order of columns. In case a single column changes place + because the user dragged it to a new location, the EVT_HEADER_END_REORDER + event handler can be used to react to this. If this event + handler is not defined though UpdateColumnsOrder() will be called + instead. A typical implementation in a derived class will update the display order of the columns in the associated control, if any. Notice that diff --git a/src/common/headerctrlcmn.cpp b/src/common/headerctrlcmn.cpp index a7787c46ab..ee284267cf 100644 --- a/src/common/headerctrlcmn.cpp +++ b/src/common/headerctrlcmn.cpp @@ -317,6 +317,7 @@ bool wxHeaderCtrlBase::ShowColumnsMenu(const wxPoint& pt, const wxString& title) { const int columnIndex = rc - wxID_COLUMNS_BASE; UpdateColumnVisibility(columnIndex, !GetColumn(columnIndex).IsShown()); + UpdateColumn(columnIndex); } return true; @@ -469,6 +470,19 @@ wxHeaderCtrlSimple::UpdateColumnWidthToFit(unsigned int idx, int widthTitle) return true; } +void +wxHeaderCtrlSimple::UpdateColumnVisibility(unsigned int idx, bool show) +{ + ShowColumn(idx, show); +} + +void +wxHeaderCtrlSimple::UpdateColumnsOrder(const wxArrayInt& WXUNUSED(order)) +{ + // Nothing to do here, we only override this function to prevent the base + // class version from asserting that it should be implemented. +} + void wxHeaderCtrlSimple::OnHeaderResizing(wxHeaderCtrlEvent& evt) { m_cols[evt.GetColumn()].SetWidth(evt.GetWidth()); diff --git a/src/generic/headerctrlg.cpp b/src/generic/headerctrlg.cpp index d24a615f9f..8df6a27826 100644 --- a/src/generic/headerctrlg.cpp +++ b/src/generic/headerctrlg.cpp @@ -456,7 +456,22 @@ bool wxHeaderCtrl::EndReordering(int xPhysical) const unsigned pos = GetColumnPos(colNew); event.SetNewOrder(pos); - if ( !GetEventHandler()->ProcessEvent(event) || event.IsAllowed() ) + const bool processed = GetEventHandler()->ProcessEvent(event); + + if ( !processed ) + { + // get the reordered columns + wxArrayInt order = GetColumnsOrder(); + MoveColumnInOrderArray(order, colOld, pos); + + // As the event wasn't processed, call the virtual function + // callback. + UpdateColumnsOrder(order); + + // update columns order + SetColumnsOrder(order); + } + else if ( event.IsAllowed() ) { // do reorder the columns DoMoveCol(colOld, pos); diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index a0b474c8ab..56e3eb2e40 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -990,7 +990,17 @@ bool wxMSWHeaderCtrl::MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) // internal column indices array if this is allowed to go ahead as // the native control is going to reorder its columns now if ( evtType == wxEVT_HEADER_END_REORDER ) - m_header.MoveColumnInOrderArray(m_colIndices, idx, order); + { + // If the event handler didn't process the event, call the + // virtual function callback. + wxArrayInt colIndices = m_header.GetColumnsOrder(); + m_header.MoveColumnInOrderArray(colIndices, idx, order); + if ( !processed ) + m_header.UpdateColumnsOrder(colIndices); + + // And update internally columns indices in any case. + m_colIndices = colIndices; + } if ( processed ) { From a79759d999bda5f26543b675936d3b212a47ab2f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 31 Dec 2023 18:03:22 +0100 Subject: [PATCH 162/257] Switch wxMSW 32 bit cross build workflow to Debian Stable Debian Testing doesn't have 32-bit support any more. --- .github/workflows/ci_msw_cross.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci_msw_cross.yml b/.github/workflows/ci_msw_cross.yml index ff5e6e4c9f..f62ec41e41 100644 --- a/.github/workflows/ci_msw_cross.yml +++ b/.github/workflows/ci_msw_cross.yml @@ -68,17 +68,21 @@ jobs: # versions of MinGW and Wine and is simpler to test with locally than the # bespoke container used by GitHub Actions by default. runs-on: ubuntu-latest - container: debian:testing-slim + container: debian:${{ matrix.debian_release }}-slim name: ${{ matrix.name }} strategy: fail-fast: false matrix: include: - name: wxMSW 64 bits + debian_release: testing configure_flags: --disable-compat32 - name: wxMSW 32 bits + # Testing doesn't have 32 bit support any more. + debian_release: stable triplet: i686-w64-mingw32 - name: wxMSW/Univ + debian_release: testing configure_flags: --enable-universal --disable-compat32 --disable-debug --disable-optimise minimal: true env: From acf113f3f90dac3ec92af0c193fc53ea3e3bd9d4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 00:00:00 +0000 Subject: [PATCH 163/257] Update copyright years to 2024 Just run misc/scripts/inc_year and commit the results. See #18690. --- CMakeLists.txt | 2 +- build/bakefiles/mac_bundles.bkl | 6 +++--- docs/doxygen/mainpages/copyright.h | 2 +- docs/doxygen/regen.sh | 2 +- interface/wx/aboutdlg.h | 2 +- interface/wx/generic/aboutdlgg.h | 2 +- samples/minimal/Info_cocoa.plist | 6 +++--- src/common/utilscmn.cpp | 2 +- src/msw/version.rc | 2 +- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b4bbf68ef6..89cb1b1f9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,7 +88,7 @@ math(EXPR wxSOVERSION_MAJOR "${WX_CURRENT} - ${WX_AGE}") set(wxSOVERSION ${wxSOVERSION_MAJOR}.${WX_AGE}.${WX_REVISION}) set(wxVERSION ${wxMAJOR_VERSION}.${wxMINOR_VERSION}.${wxRELEASE_NUMBER}) -set(wxCOPYRIGHT "2002-2023 wxWidgets") +set(wxCOPYRIGHT "2002-2024 wxWidgets") set(wxLANGUAGES C CXX) if(APPLE AND NOT CMAKE_VERSION VERSION_LESS "3.16") diff --git a/build/bakefiles/mac_bundles.bkl b/build/bakefiles/mac_bundles.bkl index 01a854c8d7..16817ca96d 100644 --- a/build/bakefiles/mac_bundles.bkl +++ b/build/bakefiles/mac_bundles.bkl @@ -49,10 +49,10 @@ sed -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_GUI_IDENTIFIER}/org.wxwidgets.$(id)/" \ -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_EXECUTABLE_NAME}/$(id)/" \ -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_BUNDLE_NAME}/$(id)/" \ - -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_COPYRIGHT}/Copyright 2002-2023 wxWidgets/" \ + -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_COPYRIGHT}/Copyright 2002-2024 wxWidgets/" \ -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_BUNDLE_VERSION}/$(WX_VERSION)/" \ - -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_INFO_STRING}/$(id) version $(WX_VERSION), (c) 2002-2023 wxWidgets/" \ - -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_LONG_VERSION_STRING}/$(WX_VERSION), (c) 2002-2023 wxWidgets/" \ + -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_INFO_STRING}/$(id) version $(WX_VERSION), (c) 2002-2024 wxWidgets/" \ + -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_LONG_VERSION_STRING}/$(WX_VERSION), (c) 2002-2024 wxWidgets/" \ -e "s/\$(DOLLAR)$(DOLLAR){MACOSX_BUNDLE_SHORT_VERSION_STRING}/$(WX_RELEASE)/" \ $(BUNDLE_PLIST) >$(BUNDLE)/Info.plist diff --git a/docs/doxygen/mainpages/copyright.h b/docs/doxygen/mainpages/copyright.h index 1270b3a2e0..90c5affb13 100644 --- a/docs/doxygen/mainpages/copyright.h +++ b/docs/doxygen/mainpages/copyright.h @@ -11,7 +11,7 @@ @section section_copyright wxWidgets Copyrights and Licenses -Copyright (c) 1992-2023 Julian Smart, Vadim Zeitlin, Stefan Csomor, Robert +Copyright (c) 1992-2024 Julian Smart, Vadim Zeitlin, Stefan Csomor, Robert Roebling, and other members of the wxWidgets team, please see the acknowledgements section below. diff --git a/docs/doxygen/regen.sh b/docs/doxygen/regen.sh index efd5b340e5..5e315f2d22 100755 --- a/docs/doxygen/regen.sh +++ b/docs/doxygen/regen.sh @@ -215,7 +215,7 @@ if [[ "$1" = "docset" ]]; then $PLIST_WRITE_CMD $DESTINATIONDIR/$DOCSETNAME/Contents/Info DocSetFeedURL $ATOMDIR/$ATOM $PLIST_WRITE_CMD $DESTINATIONDIR/$DOCSETNAME/Contents/Info DocSetFallbackURL https://docs.wxwidgets.org $PLIST_WRITE_CMD $DESTINATIONDIR/$DOCSETNAME/Contents/Info DocSetDescription "API reference and conceptual documentation for wxWidgets 3.0" - $PLIST_WRITE_CMD $DESTINATIONDIR/$DOCSETNAME/Contents/Info NSHumanReadableCopyright "Copyright 1992-2023 wxWidgets team, Portions 1996 Artificial Intelligence Applications Institute" + $PLIST_WRITE_CMD $DESTINATIONDIR/$DOCSETNAME/Contents/Info NSHumanReadableCopyright "Copyright 1992-2024 wxWidgets team, Portions 1996 Artificial Intelligence Applications Institute" $PLIST_WRITE_CMD $DESTINATIONDIR/$DOCSETNAME/Contents/Info isJavaScriptEnabled true $PLIST_WRITE_CMD $DESTINATIONDIR/$DOCSETNAME/Contents/Info dashIndexFilePath index.html $PLIST_WRITE_CMD $DESTINATIONDIR/$DOCSETNAME/Contents/Info DocSetPlatformFamily wx diff --git a/interface/wx/aboutdlg.h b/interface/wx/aboutdlg.h index 84cf275683..a245c872d8 100644 --- a/interface/wx/aboutdlg.h +++ b/interface/wx/aboutdlg.h @@ -37,7 +37,7 @@ aboutInfo.SetName("MyApp"); aboutInfo.SetVersion(MY_APP_VERSION_STRING); aboutInfo.SetDescription(_("My wxWidgets-based application!")); - aboutInfo.SetCopyright("(C) 1992-2023"); + aboutInfo.SetCopyright("(C) 1992-2024"); aboutInfo.SetWebSite("http://myapp.org"); aboutInfo.AddDeveloper("My Self"); diff --git a/interface/wx/generic/aboutdlgg.h b/interface/wx/generic/aboutdlgg.h index da993fabdb..b62b846d6a 100644 --- a/interface/wx/generic/aboutdlgg.h +++ b/interface/wx/generic/aboutdlgg.h @@ -34,7 +34,7 @@ aboutInfo.SetName("MyApp"); aboutInfo.SetVersion(MY_APP_VERSION_STRING); aboutInfo.SetDescription(_("My wxWidgets-based application!")); - aboutInfo.SetCopyright("(C) 1992-2023"); + aboutInfo.SetCopyright("(C) 1992-2024"); aboutInfo.SetWebSite("http://myapp.org"); aboutInfo.AddDeveloper("My Self"); diff --git a/samples/minimal/Info_cocoa.plist b/samples/minimal/Info_cocoa.plist index 4dd85300c6..db96a4a67b 100644 --- a/samples/minimal/Info_cocoa.plist +++ b/samples/minimal/Info_cocoa.plist @@ -7,7 +7,7 @@ CFBundleExecutable $(PRODUCT_NAME) CFBundleGetInfoString - $(PRODUCT_NAME) version 3.3.0, (c) 2005-2023 wxWidgets + $(PRODUCT_NAME) version 3.3.0, (c) 2005-2024 wxWidgets CFBundleIconFile wxmac.icns CFBundleIdentifier @@ -15,7 +15,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - 3.3.0, (c) 2005-2023 wxWidgets + 3.3.0, (c) 2005-2024 wxWidgets CFBundleName $(PRODUCT_NAME) CFBundlePackageType @@ -25,7 +25,7 @@ CFBundleVersion 3.3.0 NSHumanReadableCopyright - Copyright 2005-2023 wxWidgets + Copyright 2005-2024 wxWidgets NSPrincipalClass wxNSApplication LSMinimumSystemVersion diff --git a/src/common/utilscmn.cpp b/src/common/utilscmn.cpp index 6fe7eee522..abbdadd4dc 100644 --- a/src/common/utilscmn.cpp +++ b/src/common/utilscmn.cpp @@ -1437,7 +1437,7 @@ wxVersionInfo wxGetLibraryVersionInfo() wxMINOR_VERSION, wxRELEASE_NUMBER, msg, - wxString::Format(wxS("Copyright %s 1992-2023 wxWidgets team"), + wxString::Format(wxS("Copyright %s 1992-2024 wxWidgets team"), copyrightSign)); } diff --git a/src/msw/version.rc b/src/msw/version.rc index 085bcbcc6b..d78d80dccc 100644 --- a/src/msw/version.rc +++ b/src/msw/version.rc @@ -86,7 +86,7 @@ BEGIN VALUE "FileDescription", "wxWidgets " WXLIBDESC " library\0" VALUE "FileVersion", wxVERSION_NUM_DOT_STRING "\0" VALUE "InternalName", wxSTRINGIZE(WXDLLNAME) "\0" - VALUE "LegalCopyright", L"Copyright \xa9 1992-2023 wxWidgets development team\0" + VALUE "LegalCopyright", L"Copyright \xa9 1992-2024 wxWidgets development team\0" VALUE "OriginalFilename", wxSTRINGIZE(WXDLLNAME) ".dll\0" VALUE "ProductName", "wxWidgets\0" VALUE "ProductVersion", wxVERSION_NUM_DOT_STRING "\0" From efc943b59d199feb6b3ce193a481b92f69bba8ca Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 20:29:03 +0100 Subject: [PATCH 164/257] Remove unused wxXmlParsingContext::conv member This pointer was always null since the changes of 4519d8e08a (Remove wxUSE_UNICODE checks as they're always true now, 2022-10-27), so remove it completely. --- src/xml/xml.cpp | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index 0cd69a8cf5..d7b6338fe4 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -606,12 +606,9 @@ void wxXmlDocument::AppendToProlog(wxXmlNode *node) // wxXmlDocument loading routines //----------------------------------------------------------------------------- -// converts Expat-produced string in UTF-8 into wxString using the specified -// conv or keep in UTF-8 if conv is null -static wxString CharToString(wxMBConv *conv, - const char *s, size_t len = wxString::npos) +// converts Expat-produced string in UTF-8 into wxString: this is trivial now +static wxString CharToString(const char *s, size_t len = wxString::npos) { - wxUnusedVar(conv); return wxString::FromUTF8Unchecked(s, len); } @@ -631,8 +628,7 @@ bool wxIsWhiteOnly(const wxString& buf) struct wxXmlParsingContext { wxXmlParsingContext() - : conv(nullptr), - node(nullptr), + : node(nullptr), lastChild(nullptr), lastAsText(nullptr), doctype(nullptr), @@ -640,7 +636,6 @@ struct wxXmlParsingContext {} XML_Parser parser; - wxMBConv *conv; wxXmlNode *node; // the node being parsed wxXmlNode *lastChild; // the last child of "node" wxXmlNode *lastAsText; // the last _text_ child of "node" @@ -662,7 +657,7 @@ static void StartElementHnd(void *userData, const char *name, const char **atts) { wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData; wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, - CharToString(ctx->conv, name), + CharToString(name), wxEmptyString, XML_GetCurrentLineNumber(ctx->parser)); const char **a = atts; @@ -670,7 +665,7 @@ static void StartElementHnd(void *userData, const char *name, const char **atts) // add node attributes while (*a) { - node->AddAttribute(CharToString(ctx->conv, a[0]), CharToString(ctx->conv, a[1])); + node->AddAttribute(CharToString(a[0]), CharToString(a[1])); a += 2; } @@ -698,7 +693,7 @@ static void EndElementHnd(void *userData, const char* WXUNUSED(name)) static void TextHnd(void *userData, const char *s, int len) { wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData; - wxString str = CharToString(ctx->conv, s, len); + wxString str = CharToString(s, len); if (ctx->lastAsText) { @@ -753,7 +748,7 @@ static void CommentHnd(void *userData, const char *data) wxXmlNode *commentnode = new wxXmlNode(wxXML_COMMENT_NODE, - wxS("comment"), CharToString(ctx->conv, data), + wxS("comment"), CharToString(data), XML_GetCurrentLineNumber(ctx->parser)); ASSERT_LAST_CHILD_OK(ctx); @@ -767,8 +762,8 @@ static void PIHnd(void *userData, const char *target, const char *data) wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData; wxXmlNode *pinode = - new wxXmlNode(wxXML_PI_NODE, CharToString(ctx->conv, target), - CharToString(ctx->conv, data), + new wxXmlNode(wxXML_PI_NODE, CharToString(target), + CharToString(data), XML_GetCurrentLineNumber(ctx->parser)); ASSERT_LAST_CHILD_OK(ctx); @@ -783,9 +778,9 @@ static void StartDoctypeHnd(void *userData, const char *doctypeName, { wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData; - *ctx->doctype = wxXmlDoctype(CharToString(ctx->conv, doctypeName), - CharToString(ctx->conv, sysid), - CharToString(ctx->conv, pubid)); + *ctx->doctype = wxXmlDoctype(CharToString(doctypeName), + CharToString(sysid), + CharToString(pubid)); } static void EndDoctypeHnd(void *WXUNUSED(userData)) @@ -799,7 +794,7 @@ static void DefaultHnd(void *userData, const char *s, int len) { wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData; - wxString buf = CharToString(ctx->conv, s, (size_t)len); + wxString buf = CharToString(s, (size_t)len); int pos; pos = buf.Find(wxS("encoding=")); if (pos != wxNOT_FOUND) @@ -855,7 +850,6 @@ bool wxXmlDocument::Load(wxInputStream& stream, const wxString& encoding, int fl wxXmlNode *root = new wxXmlNode(wxXML_DOCUMENT_NODE, wxEmptyString); ctx.encoding = wxS("UTF-8"); // default in absence of encoding="" - ctx.conv = nullptr; ctx.doctype = &m_doctype; ctx.removeWhiteOnlyNodes = (flags & wxXMLDOC_KEEP_WHITESPACE_NODES) == 0; ctx.parser = parser; From 7f6d85d60b7cf2f5586f37b9a901d758586e034a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 20:30:03 +0100 Subject: [PATCH 165/257] Remove trivial CharToString() from wxXML code Just use wxString::FromUTF8Unchecked() directly. Note that Expat strings are always (valid) UTF-8 strings. --- src/xml/xml.cpp | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index d7b6338fe4..60ca5c4215 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -606,12 +606,6 @@ void wxXmlDocument::AppendToProlog(wxXmlNode *node) // wxXmlDocument loading routines //----------------------------------------------------------------------------- -// converts Expat-produced string in UTF-8 into wxString: this is trivial now -static wxString CharToString(const char *s, size_t len = wxString::npos) -{ - return wxString::FromUTF8Unchecked(s, len); -} - // returns true if the given string contains only whitespaces bool wxIsWhiteOnly(const wxString& buf) { @@ -657,7 +651,7 @@ static void StartElementHnd(void *userData, const char *name, const char **atts) { wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData; wxXmlNode *node = new wxXmlNode(wxXML_ELEMENT_NODE, - CharToString(name), + wxString::FromUTF8Unchecked(name), wxEmptyString, XML_GetCurrentLineNumber(ctx->parser)); const char **a = atts; @@ -665,7 +659,7 @@ static void StartElementHnd(void *userData, const char *name, const char **atts) // add node attributes while (*a) { - node->AddAttribute(CharToString(a[0]), CharToString(a[1])); + node->AddAttribute(wxString::FromUTF8Unchecked(a[0]), wxString::FromUTF8Unchecked(a[1])); a += 2; } @@ -693,7 +687,7 @@ static void EndElementHnd(void *userData, const char* WXUNUSED(name)) static void TextHnd(void *userData, const char *s, int len) { wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData; - wxString str = CharToString(s, len); + wxString str = wxString::FromUTF8Unchecked(s, len); if (ctx->lastAsText) { @@ -748,7 +742,7 @@ static void CommentHnd(void *userData, const char *data) wxXmlNode *commentnode = new wxXmlNode(wxXML_COMMENT_NODE, - wxS("comment"), CharToString(data), + wxS("comment"), wxString::FromUTF8Unchecked(data), XML_GetCurrentLineNumber(ctx->parser)); ASSERT_LAST_CHILD_OK(ctx); @@ -762,8 +756,8 @@ static void PIHnd(void *userData, const char *target, const char *data) wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData; wxXmlNode *pinode = - new wxXmlNode(wxXML_PI_NODE, CharToString(target), - CharToString(data), + new wxXmlNode(wxXML_PI_NODE, wxString::FromUTF8Unchecked(target), + wxString::FromUTF8Unchecked(data), XML_GetCurrentLineNumber(ctx->parser)); ASSERT_LAST_CHILD_OK(ctx); @@ -778,9 +772,9 @@ static void StartDoctypeHnd(void *userData, const char *doctypeName, { wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData; - *ctx->doctype = wxXmlDoctype(CharToString(doctypeName), - CharToString(sysid), - CharToString(pubid)); + *ctx->doctype = wxXmlDoctype(wxString::FromUTF8Unchecked(doctypeName), + wxString::FromUTF8Unchecked(sysid), + wxString::FromUTF8Unchecked(pubid)); } static void EndDoctypeHnd(void *WXUNUSED(userData)) @@ -794,7 +788,7 @@ static void DefaultHnd(void *userData, const char *s, int len) { wxXmlParsingContext *ctx = (wxXmlParsingContext*)userData; - wxString buf = CharToString(s, (size_t)len); + wxString buf = wxString::FromUTF8Unchecked(s, (size_t)len); int pos; pos = buf.Find(wxS("encoding=")); if (pos != wxNOT_FOUND) From 08ef52671f6442b44c00bebd68c04f1f19a47a35 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 20:39:18 +0100 Subject: [PATCH 166/257] Initialize wxXmlDocument::m_fileType and m_eol in declaration This is simpler and more clear than calling SetFileType() from all ctors. Also m_eol --- include/wx/xml/xml.h | 4 ++-- src/xml/xml.cpp | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/include/wx/xml/xml.h b/include/wx/xml/xml.h index 485f706932..787afeabef 100644 --- a/include/wx/xml/xml.h +++ b/include/wx/xml/xml.h @@ -284,8 +284,8 @@ private: wxString m_fileEncoding; wxXmlDoctype m_doctype; wxXmlNode *m_docNode; - wxTextFileType m_fileType; - wxString m_eol; + wxTextFileType m_fileType = wxTextFileType_Unix; + wxString m_eol = wxS("\n"); void DoCopy(const wxXmlDocument& doc); diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index 60ca5c4215..3abd92f7d1 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -442,14 +442,11 @@ bool wxXmlDoctype::IsValid() const wxXmlDocument::wxXmlDocument() : m_version(wxS("1.0")), m_fileEncoding(wxS("UTF-8")), m_docNode(nullptr) { - SetFileType(wxTextFileType_Unix); } wxXmlDocument::wxXmlDocument(const wxString& filename, const wxString& encoding) :wxObject(), m_docNode(nullptr) { - SetFileType(wxTextFileType_Unix); - if ( !Load(filename, encoding) ) { wxDELETE(m_docNode); @@ -459,8 +456,6 @@ wxXmlDocument::wxXmlDocument(const wxString& filename, const wxString& encoding) wxXmlDocument::wxXmlDocument(wxInputStream& stream, const wxString& encoding) :wxObject(), m_docNode(nullptr) { - SetFileType(wxTextFileType_Unix); - if ( !Load(stream, encoding) ) { wxDELETE(m_docNode); From 326876eb6076f23b07c573c1aab6d5ee15d634cb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 20:42:29 +0100 Subject: [PATCH 167/257] Initialize wxXmlDocument::m_docNode in its declaration too Similar to the previous commit. --- include/wx/xml/xml.h | 2 +- src/xml/xml.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/wx/xml/xml.h b/include/wx/xml/xml.h index 787afeabef..1ece0f1f41 100644 --- a/include/wx/xml/xml.h +++ b/include/wx/xml/xml.h @@ -283,7 +283,7 @@ private: wxString m_version; wxString m_fileEncoding; wxXmlDoctype m_doctype; - wxXmlNode *m_docNode; + wxXmlNode *m_docNode = nullptr; wxTextFileType m_fileType = wxTextFileType_Unix; wxString m_eol = wxS("\n"); diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index 3abd92f7d1..71c547810d 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -440,12 +440,12 @@ bool wxXmlDoctype::IsValid() const //----------------------------------------------------------------------------- wxXmlDocument::wxXmlDocument() - : m_version(wxS("1.0")), m_fileEncoding(wxS("UTF-8")), m_docNode(nullptr) + : m_version(wxS("1.0")), m_fileEncoding(wxS("UTF-8")) { } wxXmlDocument::wxXmlDocument(const wxString& filename, const wxString& encoding) - :wxObject(), m_docNode(nullptr) + :wxObject() { if ( !Load(filename, encoding) ) { @@ -454,7 +454,7 @@ wxXmlDocument::wxXmlDocument(const wxString& filename, const wxString& encoding) } wxXmlDocument::wxXmlDocument(wxInputStream& stream, const wxString& encoding) - :wxObject(), m_docNode(nullptr) + :wxObject() { if ( !Load(stream, encoding) ) { From 2a5eac26f48be9b0f2b52e5012fcc47b071b0a5d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 20:44:41 +0100 Subject: [PATCH 168/257] Remove unnecessary calls to wxDELETE() Replace them with just calls to delete as it doesn't matter if the pointer is null or not in all these cases and using just "delete" is more clear. --- include/wx/xml/xml.h | 4 ++-- src/xml/xml.cpp | 13 ++++--------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/include/wx/xml/xml.h b/include/wx/xml/xml.h index 1ece0f1f41..d262a2a42b 100644 --- a/include/wx/xml/xml.h +++ b/include/wx/xml/xml.h @@ -231,7 +231,7 @@ public: const wxString& encoding = wxT("UTF-8")); wxXmlDocument(wxInputStream& stream, const wxString& encoding = wxT("UTF-8")); - virtual ~wxXmlDocument() { wxDELETE(m_docNode); } + virtual ~wxXmlDocument() { delete m_docNode; } wxXmlDocument(const wxXmlDocument& doc); wxXmlDocument& operator=(const wxXmlDocument& doc); @@ -268,7 +268,7 @@ public: // Write-access methods: wxXmlNode *DetachDocumentNode() { wxXmlNode *old=m_docNode; m_docNode=nullptr; return old; } - void SetDocumentNode(wxXmlNode *node) { wxDELETE(m_docNode); m_docNode = node; } + void SetDocumentNode(wxXmlNode *node) { delete m_docNode; m_docNode = node; } wxXmlNode *DetachRoot(); void SetRoot(wxXmlNode *node); void SetVersion(const wxString& version) { m_version = version; } diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index 71c547810d..d9231e2122 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -447,19 +447,13 @@ wxXmlDocument::wxXmlDocument() wxXmlDocument::wxXmlDocument(const wxString& filename, const wxString& encoding) :wxObject() { - if ( !Load(filename, encoding) ) - { - wxDELETE(m_docNode); - } + Load(filename, encoding); } wxXmlDocument::wxXmlDocument(wxInputStream& stream, const wxString& encoding) :wxObject() { - if ( !Load(stream, encoding) ) - { - wxDELETE(m_docNode); - } + Load(stream, encoding); } wxXmlDocument::wxXmlDocument(const wxXmlDocument& doc) @@ -470,7 +464,8 @@ wxXmlDocument::wxXmlDocument(const wxXmlDocument& doc) wxXmlDocument& wxXmlDocument::operator=(const wxXmlDocument& doc) { - wxDELETE(m_docNode); + delete m_docNode; + DoCopy(doc); return *this; } From 0b049be4b7e9d8ddd352bc92e003adc2cb241dbf Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 20:47:58 +0100 Subject: [PATCH 169/257] Use unique_ptr<> in wxXmlDocument Replace manual use of raw pointer with std::unique_ptr<>. No real changes. --- include/wx/xml/xml.h | 12 +++++++----- src/xml/xml.cpp | 18 ++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/wx/xml/xml.h b/include/wx/xml/xml.h index d262a2a42b..7f24e71258 100644 --- a/include/wx/xml/xml.h +++ b/include/wx/xml/xml.h @@ -21,6 +21,8 @@ #include "wx/textbuf.h" #include "wx/versioninfo.h" +#include + #ifdef WXMAKINGDLL_XML #define WXDLLIMPEXP_XML WXEXPORT #elif defined(WXUSINGDLL) @@ -231,7 +233,7 @@ public: const wxString& encoding = wxT("UTF-8")); wxXmlDocument(wxInputStream& stream, const wxString& encoding = wxT("UTF-8")); - virtual ~wxXmlDocument() { delete m_docNode; } + ~wxXmlDocument() = default; wxXmlDocument(const wxXmlDocument& doc); wxXmlDocument& operator=(const wxXmlDocument& doc); @@ -252,7 +254,7 @@ public: // Returns root node of the document. wxXmlNode *GetRoot() const; // Returns the document node. - wxXmlNode *GetDocumentNode() const { return m_docNode; } + wxXmlNode *GetDocumentNode() const { return m_docNode.get(); } // Returns version of document (may be empty). @@ -267,8 +269,8 @@ public: wxString GetEOL() const { return m_eol; } // Write-access methods: - wxXmlNode *DetachDocumentNode() { wxXmlNode *old=m_docNode; m_docNode=nullptr; return old; } - void SetDocumentNode(wxXmlNode *node) { delete m_docNode; m_docNode = node; } + wxXmlNode *DetachDocumentNode() { return m_docNode.release(); } + void SetDocumentNode(wxXmlNode *node) { m_docNode.reset(node); } wxXmlNode *DetachRoot(); void SetRoot(wxXmlNode *node); void SetVersion(const wxString& version) { m_version = version; } @@ -283,7 +285,7 @@ private: wxString m_version; wxString m_fileEncoding; wxXmlDoctype m_doctype; - wxXmlNode *m_docNode = nullptr; + std::unique_ptr m_docNode; wxTextFileType m_fileType = wxTextFileType_Unix; wxString m_eol = wxS("\n"); diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index d9231e2122..b1971eb3a1 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -464,8 +464,6 @@ wxXmlDocument::wxXmlDocument(const wxXmlDocument& doc) wxXmlDocument& wxXmlDocument::operator=(const wxXmlDocument& doc) { - delete m_docNode; - DoCopy(doc); return *this; } @@ -479,9 +477,9 @@ void wxXmlDocument::DoCopy(const wxXmlDocument& doc) m_eol = doc.m_eol; if (doc.m_docNode) - m_docNode = new wxXmlNode(*doc.m_docNode); + m_docNode.reset(new wxXmlNode(*doc.m_docNode)); else - m_docNode = nullptr; + m_docNode.reset(); } bool wxXmlDocument::Load(const wxString& filename, const wxString& encoding, int flags) @@ -502,7 +500,7 @@ bool wxXmlDocument::Save(const wxString& filename, int indentstep) const wxXmlNode *wxXmlDocument::GetRoot() const { - wxXmlNode *node = m_docNode; + wxXmlNode *node = m_docNode.get(); if (node) { node = m_docNode->GetChildren(); @@ -514,7 +512,7 @@ wxXmlNode *wxXmlDocument::GetRoot() const wxXmlNode *wxXmlDocument::DetachRoot() { - wxXmlNode *node = m_docNode; + wxXmlNode *node = m_docNode.get(); if (node) { node = m_docNode->GetChildren(); @@ -547,7 +545,7 @@ void wxXmlDocument::SetRoot(wxXmlNode *root) "Can only set an element type node as root" ); } - wxXmlNode *node = m_docNode; + wxXmlNode *node = m_docNode.get(); if (node) { node = m_docNode->GetChildren(); @@ -569,11 +567,11 @@ void wxXmlDocument::SetRoot(wxXmlNode *root) } else { - m_docNode = new wxXmlNode(wxXML_DOCUMENT_NODE, wxEmptyString); + m_docNode.reset(new wxXmlNode(wxXML_DOCUMENT_NODE, wxEmptyString)); m_docNode->SetChildren(root); } if (root) - root->SetParent(m_docNode); + root->SetParent(m_docNode.get()); } void wxXmlDocument::SetFileType(wxTextFileType fileType) @@ -585,7 +583,7 @@ void wxXmlDocument::SetFileType(wxTextFileType fileType) void wxXmlDocument::AppendToProlog(wxXmlNode *node) { if (!m_docNode) - m_docNode = new wxXmlNode(wxXML_DOCUMENT_NODE, wxEmptyString); + m_docNode.reset(new wxXmlNode(wxXML_DOCUMENT_NODE, wxEmptyString)); if (IsOk()) m_docNode->InsertChild( node, GetRoot() ); else From 9ee9f4e8dd5f0b5ae10954f106af031e757b401b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 21:00:08 +0100 Subject: [PATCH 170/257] Remove documentation of wxXmlDocument::GetEncoding() This function was removed in 4519d8e08a (Remove wxUSE_UNICODE checks as they're always true now, 2022-10-27). --- interface/wx/xml/xml.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/interface/wx/xml/xml.h b/interface/wx/xml/xml.h index ebfda1be2b..9c589b6eec 100644 --- a/interface/wx/xml/xml.h +++ b/interface/wx/xml/xml.h @@ -760,14 +760,6 @@ public: */ wxXmlNode* DetachRoot(); - /** - Returns encoding of in-memory representation of the document - (same as passed to Load() or constructor, defaults to UTF-8). - - @note this is meaningless in Unicode build where data are stored as @c wchar_t*. - */ - wxString GetEncoding() const; - /** Returns encoding of document (may be empty). From 268b2b98e0c30b162d64633654ad5e19bfa67a27 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 22:04:41 +0100 Subject: [PATCH 171/257] Use WaitForEventAt() in Grid::ReorderedColumnsCellClick test too This test also sporadically fails on AppVeyor. --- tests/controls/gridtest.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 97557eb5bc..a77f2ad39d 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -534,8 +534,10 @@ TEST_CASE_METHOD(GridTestCase, "Grid::ReorderedColumnsCellClick", "[grid]") wxYield(); sim.MouseClick(); - wxYield(); - + if ( !WaitForEventAt(point, "mouse click to be processed", [&]() { + return click.GetCount() != 0; + }) ) + return; CHECK(click.GetCount() == 1); #endif } From 20845d85a5a41ae49ca6a422ad150dcd9d4c8959 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 21:00:50 +0100 Subject: [PATCH 172/257] Deprecate "encoding" parameter of wxXmlDocument ctor and Load() This parameter wasn't used for anything as it specified the encoding of the data contents in memory and not the encoding of the XML file as might be believed, so it only created unnecessary confusion. See #24167. --- include/wx/xml/xml.h | 42 +++++++++++++++++++++++++++++------- interface/wx/xml/xml.h | 18 ++++++---------- src/richtext/richtextxml.cpp | 5 +---- src/xml/xml.cpp | 16 ++++++-------- src/xrc/xmlres.cpp | 4 +--- tests/xml/xmltest.cpp | 2 +- tests/xml/xrctest.cpp | 4 ++-- 7 files changed, 53 insertions(+), 38 deletions(-) diff --git a/include/wx/xml/xml.h b/include/wx/xml/xml.h index 7f24e71258..f65db2edf5 100644 --- a/include/wx/xml/xml.h +++ b/include/wx/xml/xml.h @@ -229,10 +229,8 @@ class WXDLLIMPEXP_XML wxXmlDocument : public wxObject { public: wxXmlDocument(); - wxXmlDocument(const wxString& filename, - const wxString& encoding = wxT("UTF-8")); - wxXmlDocument(wxInputStream& stream, - const wxString& encoding = wxT("UTF-8")); + wxXmlDocument(const wxString& filename); + wxXmlDocument(wxInputStream& stream); ~wxXmlDocument() = default; wxXmlDocument(const wxXmlDocument& doc); @@ -240,10 +238,8 @@ public: // Parses .xml file and loads data. Returns TRUE on success, FALSE // otherwise. - virtual bool Load(const wxString& filename, - const wxString& encoding = wxT("UTF-8"), int flags = wxXMLDOC_NONE); - virtual bool Load(wxInputStream& stream, - const wxString& encoding = wxT("UTF-8"), int flags = wxXMLDOC_NONE); + bool Load(const wxString& filename, int flags = wxXMLDOC_NONE); + bool Load(wxInputStream& stream, int flags = wxXMLDOC_NONE); // Saves document as .xml file. virtual bool Save(const wxString& filename, int indentstep = 2) const; @@ -281,6 +277,36 @@ public: static wxVersionInfo GetLibraryVersionInfo(); +#ifdef WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("Remove encoding parameter from the call") + wxXmlDocument(const wxString& filename, + const wxString& WXUNUSED(encoding)) + : wxXmlDocument(filename) + { + } + + wxDEPRECATED_MSG("Remove encoding parameter from the call") + wxXmlDocument(wxInputStream& stream, + const wxString& WXUNUSED(encoding)) + : wxXmlDocument(stream) + { + } + + wxDEPRECATED_MSG("Remove encoding parameter from the call") + bool Load(const wxString& filename, + const wxString& WXUNUSED(encoding), int flags = wxXMLDOC_NONE) + { + return Load(filename, flags); + } + + wxDEPRECATED_MSG("Remove encoding parameter from the call") + bool Load(wxInputStream& stream, + const wxString& WXUNUSED(encoding), int flags = wxXMLDOC_NONE) + { + return Load(stream, flags); + } +#endif // WXWIN_COMPATIBILITY_3_2 + private: wxString m_version; wxString m_fileEncoding; diff --git a/interface/wx/xml/xml.h b/interface/wx/xml/xml.h index 9c589b6eec..0d6b5a960a 100644 --- a/interface/wx/xml/xml.h +++ b/interface/wx/xml/xml.h @@ -637,7 +637,7 @@ enum wxXmlDocumentLoadFlag @code wxXmlDocument doc; - doc.Load("myfile.xml", "UTF-8", wxXMLDOC_KEEP_WHITESPACE_NODES); + doc.Load("myfile.xml", wxXMLDOC_KEEP_WHITESPACE_NODES); // myfile2.xml will be identical to myfile.xml saving it this way: doc.Save("myfile2.xml", wxXML_NO_INDENTATION); @@ -711,14 +711,12 @@ public: /** Loads the given filename using the given encoding. See Load(). */ - wxXmlDocument(const wxString& filename, - const wxString& encoding = "UTF-8"); + wxXmlDocument(const wxString& filename); /** Loads the XML document from given stream using the given encoding. See Load(). */ - wxXmlDocument(wxInputStream& stream, - const wxString& encoding = "UTF-8"); + wxXmlDocument(wxInputStream& stream); /** Virtual destructor. Frees the document root node. @@ -831,15 +829,13 @@ public: Returns true on success, false otherwise. */ - virtual bool Load(const wxString& filename, - const wxString& encoding = "UTF-8", int flags = wxXMLDOC_NONE); + bool Load(const wxString& filename, int flags = wxXMLDOC_NONE); /** - Like Load(const wxString&, const wxString&, int) but takes the data from - given input stream. + Like Load(const wxString&, int) but takes the data from given input + stream. */ - virtual bool Load(wxInputStream& stream, - const wxString& encoding = "UTF-8", int flags = wxXMLDOC_NONE); + bool Load(wxInputStream& stream, int flags = wxXMLDOC_NONE); /** Saves XML tree creating a file named with given string. diff --git a/src/richtext/richtextxml.cpp b/src/richtext/richtextxml.cpp index 3e322c31ad..66c5ecc8f4 100644 --- a/src/richtext/richtextxml.cpp +++ b/src/richtext/richtextxml.cpp @@ -76,10 +76,7 @@ bool wxRichTextXMLHandler::DoLoadFile(wxRichTextBuffer *buffer, wxInputStream& s wxXmlDocument* xmlDoc = new wxXmlDocument; bool success = true; - // This is the encoding to convert to (memory encoding rather than file encoding) - wxString encoding(wxT("UTF-8")); - - if (!xmlDoc->Load(stream, encoding)) + if (!xmlDoc->Load(stream)) { buffer->ResetAndClearCommands(); success = false; diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index b1971eb3a1..769f84db41 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -444,16 +444,16 @@ wxXmlDocument::wxXmlDocument() { } -wxXmlDocument::wxXmlDocument(const wxString& filename, const wxString& encoding) +wxXmlDocument::wxXmlDocument(const wxString& filename) :wxObject() { - Load(filename, encoding); + Load(filename); } -wxXmlDocument::wxXmlDocument(wxInputStream& stream, const wxString& encoding) +wxXmlDocument::wxXmlDocument(wxInputStream& stream) :wxObject() { - Load(stream, encoding); + Load(stream); } wxXmlDocument::wxXmlDocument(const wxXmlDocument& doc) @@ -482,12 +482,12 @@ void wxXmlDocument::DoCopy(const wxXmlDocument& doc) m_docNode.reset(); } -bool wxXmlDocument::Load(const wxString& filename, const wxString& encoding, int flags) +bool wxXmlDocument::Load(const wxString& filename, int flags) { wxFileInputStream stream(filename); if (!stream.IsOk()) return false; - return Load(stream, encoding, flags); + return Load(stream, flags); } bool wxXmlDocument::Save(const wxString& filename, int indentstep) const @@ -820,10 +820,8 @@ static int UnknownEncodingHnd(void * WXUNUSED(encodingHandlerData), } // extern "C" -bool wxXmlDocument::Load(wxInputStream& stream, const wxString& encoding, int flags) +bool wxXmlDocument::Load(wxInputStream& stream, int flags) { - (void)encoding; - const size_t BUFSIZE = 1024; char buf[BUFSIZE]; wxXmlParsingContext ctx; diff --git a/src/xrc/xmlres.cpp b/src/xrc/xmlres.cpp index c8d4f6e87a..20ce5e75c8 100644 --- a/src/xrc/xmlres.cpp +++ b/src/xrc/xmlres.cpp @@ -800,10 +800,8 @@ wxXmlDocument *wxXmlResource::DoLoadFile(const wxString& filename) return nullptr; } - wxString encoding(wxT("UTF-8")); - std::unique_ptr doc(new wxXmlDocument); - if (!doc->Load(*stream, encoding)) + if (!doc->Load(*stream)) { wxLogError(_("Cannot load resources from file '%s'."), filename); return nullptr; diff --git a/tests/xml/xmltest.cpp b/tests/xml/xmltest.cpp index f09d887d75..ac9dee4b3c 100644 --- a/tests/xml/xmltest.cpp +++ b/tests/xml/xmltest.cpp @@ -223,7 +223,7 @@ void XmlTestCase::LoadSave() ; wxStringInputStream sisp(xmlTextProlog); - CPPUNIT_ASSERT( doc.Load(sisp, "UTF-8") ); + CPPUNIT_ASSERT( doc.Load(sisp) ); wxStringOutputStream sosp; CPPUNIT_ASSERT( doc.Save(sosp) ); diff --git a/tests/xml/xrctest.cpp b/tests/xml/xrctest.cpp index 53445e8609..2e85ae0cd1 100644 --- a/tests/xml/xrctest.cpp +++ b/tests/xml/xrctest.cpp @@ -45,7 +45,7 @@ static const char *TEST_XRC_FILE = "test.xrc"; void LoadXrcFrom(const wxString& xrcText) { wxStringInputStream sis(xrcText); - std::unique_ptr xmlDoc(new wxXmlDocument(sis, "UTF-8")); + std::unique_ptr xmlDoc(new wxXmlDocument(sis)); REQUIRE( xmlDoc->IsOk() ); // Load the xrc we've just created @@ -294,7 +294,7 @@ TEST_CASE("XRC::EnvVarInPath", "[xrc]") "$(WX_TEST_ENV_IN_PATH).bmp" #endif ); - wxXmlDocument xmlDoc(sis, "UTF-8"); + wxXmlDocument xmlDoc(sis); REQUIRE( xmlDoc.IsOk() ); class wxTestEnvXmlHandler : public wxXmlResourceHandler From 8bb8eb5108aa439dee932e16a0262832f9953223 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 1 Jan 2024 21:02:45 +0100 Subject: [PATCH 173/257] Increase buffer size in wxXmlDocument::Load() The 1KB buffer used before was really too small and should have been increased to at least 4KB, but increase it to 16KB as it should do no harm neither. --- src/xml/xml.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/xml/xml.cpp b/src/xml/xml.cpp index 769f84db41..9076bf1f3c 100644 --- a/src/xml/xml.cpp +++ b/src/xml/xml.cpp @@ -822,7 +822,7 @@ static int UnknownEncodingHnd(void * WXUNUSED(encodingHandlerData), bool wxXmlDocument::Load(wxInputStream& stream, int flags) { - const size_t BUFSIZE = 1024; + const size_t BUFSIZE = 16384; char buf[BUFSIZE]; wxXmlParsingContext ctx; bool done; From 64d1d27da912e33423842101b324a52a030a4240 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Mon, 1 Jan 2024 13:46:18 -0800 Subject: [PATCH 174/257] Fix wxMM_METRIC scaling with wxGCDC for non-macOS platforms Don't override the default mm-to-pixel calculation, it will get the right answer. --- src/common/dcgraph.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index 0313014874..e0a5b0f6eb 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -212,9 +212,6 @@ wxGCDCImpl::wxGCDCImpl(wxDC* owner, int) void wxGCDCImpl::CommonInit() { - m_mm_to_pix_x = mm2pt; - m_mm_to_pix_y = mm2pt; - m_isClipBoxValid = false; m_logicalFunctionSupported = true; From a65ada2a5ec1466fa2d17567b0220af7750fff42 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Mon, 1 Jan 2024 13:52:10 -0800 Subject: [PATCH 175/257] Simplify mm-to-pixel conversion wxDisplay can already tell us the PPI, just convert it to mm. --- src/common/dcbase.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/common/dcbase.cpp b/src/common/dcbase.cpp index e1060ae402..e11e10176f 100644 --- a/src/common/dcbase.cpp +++ b/src/common/dcbase.cpp @@ -1397,13 +1397,17 @@ float wxDCImpl::GetFontPointSizeAdjustment(float dpi) return float(wxDisplay::GetStdPPIValue()) / dpi; } +static void mmToPx(wxWindow* win, double& x, double& y) +{ + const wxSize ppi(win ? wxDisplay(win).GetPPI() : wxGetDisplayPPI()); + x = ppi.x * mm2inches; + y = ppi.y * mm2inches; +} + double wxDCImpl::GetMMToPXx() const { if ( wxIsNullDouble(m_mm_to_pix_x) ) - { - m_mm_to_pix_x = (double)wxGetDisplaySize().GetWidth() / - (double)wxGetDisplaySizeMM().GetWidth(); - } + mmToPx(m_window, m_mm_to_pix_x, m_mm_to_pix_y); return m_mm_to_pix_x; } @@ -1411,10 +1415,7 @@ double wxDCImpl::GetMMToPXx() const double wxDCImpl::GetMMToPXy() const { if ( wxIsNullDouble(m_mm_to_pix_y) ) - { - m_mm_to_pix_y = (double)wxGetDisplaySize().GetHeight() / - (double)wxGetDisplaySizeMM().GetHeight(); - } + mmToPx(m_window, m_mm_to_pix_x, m_mm_to_pix_y); return m_mm_to_pix_y; } From 92b901f97198a0db8e05e4172ad6be16079656e7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 2 Jan 2024 00:50:39 +0100 Subject: [PATCH 176/257] Remove unnecessary wxUnusedVar() from wxFileConfig code No real changes, just don't use wxUnusedVar() for a parameter which is actually used. --- src/common/fileconf.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index 04b46ba448..e0c610d031 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -247,8 +247,6 @@ wxString wxFileConfig::GetGlobalDir() wxString wxFileConfig::GetLocalDir(int style) { - wxUnusedVar(style); - wxStandardPathsBase& stdp = wxStandardPaths::Get(); // it so happens that user data directory is a subdirectory of user config From 420983f76a59ca7c07f8f1b4f022b06091b244b1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 2 Jan 2024 01:47:26 +0100 Subject: [PATCH 177/257] Document that GetUserDataDir() doesn't respect XDG file layout And recommend using GetUserDir() instead. --- interface/wx/stdpaths.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/interface/wx/stdpaths.h b/interface/wx/stdpaths.h index 36be031fb6..ea83a96be6 100644 --- a/interface/wx/stdpaths.h +++ b/interface/wx/stdpaths.h @@ -376,11 +376,19 @@ public: virtual wxString GetUserConfigDir() const; /** - Return the directory for the user-dependent application data files: + Return the directory for the user-dependent application data files. + + The returned path is: + - Unix: @c ~/.appinfo - Windows: @c "C:\Users\username\AppData\Roaming\appinfo" or @c "C:\Documents and Settings\username\Application Data\appinfo" - Mac: @c "~/Library/Application Support/appinfo" + + Please note that under Unix this function return value doesn't depend + on the file layout, and so returns a possibly unexpected value when + wxStandardPaths::FileLayout_XDG is used. Consider using GetUserDir() + instead if you use XDG layout, as this function does respect it. */ virtual wxString GetUserDataDir() const; From 72c164f28c192afea1ea13ab4abc7cc6895ca65d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 2 Jan 2024 01:57:04 +0100 Subject: [PATCH 178/257] Make wxStandardPaths::AppendAppInfo() public This function can be useful to the application code and will be used by wxFileConfig in the upcoming commits. --- include/wx/stdpaths.h | 8 ++++---- interface/wx/stdpaths.h | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/include/wx/stdpaths.h b/include/wx/stdpaths.h index 3a0d5e5227..3afb5de4a5 100644 --- a/include/wx/stdpaths.h +++ b/include/wx/stdpaths.h @@ -184,6 +184,10 @@ public: bool UsesAppInfo(int info) const { return (m_usedAppInfo & info) != 0; } + // append application information determined by m_usedAppInfo to dir + wxString AppendAppInfo(const wxString& dir) const; + + void SetFileLayout(FileLayout layout) { m_fileLayout = layout; @@ -203,10 +207,6 @@ protected: // path separator or dot (.) is not already at the end of dir static wxString AppendPathComponent(const wxString& dir, const wxString& component); - // append application information determined by m_usedAppInfo to dir - wxString AppendAppInfo(const wxString& dir) const; - - // combination of AppInfo_XXX flags used by AppendAppInfo() int m_usedAppInfo; diff --git a/interface/wx/stdpaths.h b/interface/wx/stdpaths.h index ea83a96be6..40baffff73 100644 --- a/interface/wx/stdpaths.h +++ b/interface/wx/stdpaths.h @@ -195,6 +195,20 @@ public: ConfigFileConv_Ext }; + /** + Append application and/or vendor name to the given directory. + + By default, appends the subdirectory with the application name, as + returned by wxApp::GetAppName(), to the given directory. + + This behaviour is affected by UseAppInfo(), e.g. if this function is + called with `AppInfo_VendorName` then the vendor name would be appended + instead of the application name. + + @since 3.3.0 + */ + wxString AppendAppInfo(const wxString& dir) const; + /** MSW-specific function undoing the effect of IgnoreAppSubDir() calls. @@ -513,6 +527,8 @@ public: By default, only the application name is used. + @see AppendAppInfo() + @since 2.9.0 */ void UseAppInfo(int info); From d56cf71466f586785dfd1e75206736ee4e9cc963 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 2 Jan 2024 02:07:25 +0100 Subject: [PATCH 179/257] Add wxStandardPaths::Dir_Config This allows using GetUserDir(Dir_Config) to retrieve XDG-compliant location of the configuration files, independently of the file layout used by the global wxStandardPaths object. Recommend using this directory instead of GetUserDataDir() for multiple configuration files under Unix. --- include/wx/stdpaths.h | 1 + interface/wx/stdpaths.h | 16 ++++++++++++++-- src/msw/stdpaths.cpp | 3 +++ src/osx/cocoa/stdpaths.mm | 8 +++++++- src/unix/stdpaths.cpp | 6 +++++- 5 files changed, 30 insertions(+), 4 deletions(-) diff --git a/include/wx/stdpaths.h b/include/wx/stdpaths.h index 3afb5de4a5..7d0858abd8 100644 --- a/include/wx/stdpaths.h +++ b/include/wx/stdpaths.h @@ -51,6 +51,7 @@ public: enum Dir { Dir_Cache, + Dir_Config, Dir_Documents, Dir_Desktop, Dir_Downloads, diff --git a/interface/wx/stdpaths.h b/interface/wx/stdpaths.h index 40baffff73..46e55a61d7 100644 --- a/interface/wx/stdpaths.h +++ b/interface/wx/stdpaths.h @@ -79,6 +79,18 @@ public: */ Dir_Cache, + /** + Directory containing configuration information. + + Example return values: + - Unix: `~/.config` + - Windows: `C:\Users\username\AppData\Roaming` + - Mac: @c `~/Library/Preferences` + + @since 3.3.0 + */ + Dir_Config, + /** Directory containing user documents. @@ -384,8 +396,8 @@ public: - Mac: @c ~/Library/Preferences Only use this method if you have a single configuration file to put in this - directory, otherwise GetUserDataDir() is more appropriate as the latter - adds @c appinfo to the path, unlike this function. + directory, otherwise calling AppendAppInfo() with the value returned by + GetDir() with wxStandardPaths::Dir_Config is more appropriate. */ virtual wxString GetUserConfigDir() const; diff --git a/src/msw/stdpaths.cpp b/src/msw/stdpaths.cpp index 5fbaf97b1f..fca59bbfd4 100644 --- a/src/msw/stdpaths.cpp +++ b/src/msw/stdpaths.cpp @@ -189,6 +189,9 @@ wxString wxStandardPaths::GetUserDir(Dir userDir) const case Dir_Cache: csidl = CSIDL_LOCAL_APPDATA; break; + case Dir_Config: + csidl = CSIDL_APPDATA; + break; case Dir_Desktop: csidl = CSIDL_DESKTOPDIRECTORY; break; diff --git a/src/osx/cocoa/stdpaths.mm b/src/osx/cocoa/stdpaths.mm index 85418fb5af..584362c4bd 100644 --- a/src/osx/cocoa/stdpaths.mm +++ b/src/osx/cocoa/stdpaths.mm @@ -101,12 +101,18 @@ wxStandardPaths::GetLocalizedResourcesDir(const wxString& lang, wxString wxStandardPaths::GetUserDir(Dir userDir) const { + wxString subdir; + NSSearchPathDirectory dirType; switch (userDir) { case Dir_Cache: dirType = NSCachesDirectory; break; + case Dir_Config: + dirType = NSLibraryDirectory; + subdir = "/Preferences"; + break; case Dir_Desktop: dirType = NSDesktopDirectory; break; @@ -127,7 +133,7 @@ wxString wxStandardPaths::GetUserDir(Dir userDir) const break; } - return GetFMDirectory(dirType, NSUserDomainMask); + return GetFMDirectory(dirType, NSUserDomainMask) + subdir; } wxString diff --git a/src/unix/stdpaths.cpp b/src/unix/stdpaths.cpp index b492601d87..8d49f4b11b 100644 --- a/src/unix/stdpaths.cpp +++ b/src/unix/stdpaths.cpp @@ -274,7 +274,11 @@ wxString wxStandardPaths::GetUserDir(Dir userDir) const return cacheDir; } - const wxFileName dirsFile(GetXDGConfigHome(), wxS("user-dirs.dirs")); + const wxString configDir = GetXDGConfigHome(); + if (userDir == Dir_Config) + return configDir; + + const wxFileName dirsFile(configDir, wxS("user-dirs.dirs")); if ( dirsFile.FileExists() ) { wxString userDirId; From d1e223d5319a017c165666ee33a7639dd0a875df Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 2 Jan 2024 02:16:05 +0100 Subject: [PATCH 180/257] Add [[nodiscard]] attribute to wxStandardPaths::AppendAppInfo() It doesn't make sense to call this function and ignore its return value, but it may happen accidentally as it might seem that it modifies its parameter. --- include/wx/stdpaths.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/wx/stdpaths.h b/include/wx/stdpaths.h index 7d0858abd8..49b0333153 100644 --- a/include/wx/stdpaths.h +++ b/include/wx/stdpaths.h @@ -186,6 +186,7 @@ public: bool UsesAppInfo(int info) const { return (m_usedAppInfo & info) != 0; } // append application information determined by m_usedAppInfo to dir + wxNODISCARD wxString AppendAppInfo(const wxString& dir) const; From 3093d7ad4f75c4ede88bb02a8d510413782e79d1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 2 Jan 2024 02:18:45 +0100 Subject: [PATCH 181/257] Add wxCONFIG_USE_XDG to use with wxFileConfig Using this style allows to tell wxFileConfig to use XDG-compliant location for the user configuration file, even when not using XDG file layout for wxStandardPaths, which can be convenient when modifying the existing application using wxStandardPaths for other files locations too. And using it in combination with wxCONFIG_USE_SUBDIR allows to put the config file in a XDG-compliant subdirectory, which wasn't easily possible at all before. --- include/wx/confbase.h | 3 ++- interface/wx/config.h | 47 +++++++++++++++++++++++++++++++++-------- interface/wx/fileconf.h | 22 +++++++++++++++++-- src/common/fileconf.cpp | 25 +++++++++++++++++----- 4 files changed, 80 insertions(+), 17 deletions(-) diff --git a/include/wx/confbase.h b/include/wx/confbase.h index 584ca07d89..bc00ec1413 100644 --- a/include/wx/confbase.h +++ b/include/wx/confbase.h @@ -62,7 +62,8 @@ enum wxCONFIG_USE_GLOBAL_FILE = 2, wxCONFIG_USE_RELATIVE_PATH = 4, wxCONFIG_USE_NO_ESCAPE_CHARACTERS = 8, - wxCONFIG_USE_SUBDIR = 16 + wxCONFIG_USE_SUBDIR = 16, + wxCONFIG_USE_XDG = 32 }; // ---------------------------------------------------------------------------- diff --git a/interface/wx/config.h b/interface/wx/config.h index 4b9e052ab1..3e86aa9434 100644 --- a/interface/wx/config.h +++ b/interface/wx/config.h @@ -6,14 +6,41 @@ ///////////////////////////////////////////////////////////////////////////// -// Flags for constructor style parameter +/// Flags for wxConfig constructor style parameter. enum { wxCONFIG_USE_LOCAL_FILE = 1, wxCONFIG_USE_GLOBAL_FILE = 2, wxCONFIG_USE_RELATIVE_PATH = 4, wxCONFIG_USE_NO_ESCAPE_CHARACTERS = 8, - wxCONFIG_USE_SUBDIR = 16 + + /** + Use subdirectory for the local configuration file location. + + Specifying this flag changes the default local configuration file + location to `~/.appname/appname.conf`. Please note that this path is + _not_ affected by layout set using wxStandardPaths::SetFileLayout() and + it is recommended to use wxCONFIG_USE_XDG flag in addition to this file + on contemporary Linux systems. + + @since 2.8.2 + */ + wxCONFIG_USE_SUBDIR = 16, + + /** + Use XDG-compliant file location on Unix systems. + + If wxCONFIG_USE_SUBDIR is not specified, using this flag has the same + effect as calling wxStandardPaths::SetFileLayout() with + wxStandardPaths::FileLayout_XDG, i.e. it changes the default local + configuration file location to `~/.config/appname.conf`. + + In combination with wxCONFIG_USE_SUBDIR, this flag changes the default + configuration file location to ~/.config/appname/appname.conf`. + + @since 3.3.0 + */ + wxCONFIG_USE_XDG = 32 }; @@ -296,14 +323,16 @@ public: @n For wxFileConfig you can also add @c wxCONFIG_USE_RELATIVE_PATH by logically or'ing it to either of the _FILE options to tell wxFileConfig to use relative instead of absolute paths. - @n On non-VMS Unix systems, the default local configuration file is - "~/.appname". However, this path may be also used as user data + @n On Unix-like systems, the default local configuration file is + `~/.appname` unless wxStandardPaths::SetFileLayout() is called with + wxStandardPaths::FileLayout_XDG parameter in which case the default + becomes `~/.config/appname.conf`. + @n Note that this default path may be also used as user data directory (see wxStandardPaths::GetUserDataDir()) if the - application has several data files. In this case - @c wxCONFIG_USE_SUBDIR flag, which changes the default local - configuration file to "~/.appname/appname" should be used. Notice - that this flag is ignored if @a localFilename is provided. - @c wxCONFIG_USE_SUBDIR is new since wxWidgets version 2.8.2. + application has several data files. In this case it is recommended + to use ::wxCONFIG_USE_XDG flag (available since wxWidgets 3.3.0) + and/or older ::wxCONFIG_USE_SUBDIR (available since 2.8.2) to + change the default local configuration file location. @n For wxFileConfig, you can also add @c wxCONFIG_USE_NO_ESCAPE_CHARACTERS which will turn off character escaping for the values of entries stored in the config file: for diff --git a/interface/wx/fileconf.h b/interface/wx/fileconf.h index caef821174..ae91b8e481 100644 --- a/interface/wx/fileconf.h +++ b/interface/wx/fileconf.h @@ -18,6 +18,24 @@ used explicitly if you want to use files and not the registry even under Windows. + @section fileconf_paths Configuration Files Paths + + The default path for local (or user) configuration file is `~/.appname`, + i.e. it is stored directly in the user home directory. This default + path is backwards-compatible but not recommended any more and it is advised + to call wxStandardPaths::SetFileLayout() with + wxStandardPaths::FileLayout_XDG parameter to change the default path to + `~/.config/appname.conf`. + + Alternatively, it is possible to specify ::wxCONFIG_USE_XDG flag in the + style parameter of the constructor to use this XDG-compliant path without + changing the global file layout. + + And for the programs using multiple configuration files it is recommended + to use both ::wxCONFIG_USE_XDG and ::wxCONFIG_USE_SUBDIR which change the + default file path to `~/.config/appname/appname.conf` -- and allow the + program to store other files in the same `~/.config/appname` directory. + @library{wxbase} @category{cfg} @@ -71,8 +89,8 @@ public: parameter in the constructor. @a style has the same meaning as in @ref wxConfigBase::wxConfigBase "wxConfig constructor" - and can contain any combination of styles but only wxCONFIG_USE_SUBDIR bit is - examined by this function. + and can contain any combination of styles but only wxCONFIG_USE_SUBDIR + and wxCONFIG_USE_XDG are really used by this function. Notice that this function cannot be used if @a basename is already a full path name. */ diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index e0c610d031..08154612e3 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -249,8 +249,22 @@ wxString wxFileConfig::GetLocalDir(int style) { wxStandardPathsBase& stdp = wxStandardPaths::Get(); - // it so happens that user data directory is a subdirectory of user config - // directory on all supported platforms, which explains why we use it here + if ( style & wxCONFIG_USE_XDG ) + { + // When XDG-compliant layout is requested, we need to use this function + // as GetUserDataDir() doesn't support it. + wxString dir = stdp.GetUserDir(wxStandardPaths::Dir_Config); + + if ( style & wxCONFIG_USE_SUBDIR ) + dir = stdp.AppendAppInfo(dir); + + return dir; + } + + // Normally we'd like to use GetUserConfigDir() and just append app info + // subdirectories to it, but we can't do it for compatibility reasons: + // there are existing configuration files in the locations returned by + // these functions already, so return the same values as we always did. return style & wxCONFIG_USE_SUBDIR ? stdp.GetUserDataDir() : stdp.GetUserConfigDir(); } @@ -271,10 +285,11 @@ wxFileName wxFileConfig::GetLocalFile(const wxString& szFile, int style) // directly in the home directory. Note that if wxStandardPaths is // configured to follow XDG specification, all config files go to a // subdirectory of XDG_CONFIG_HOME anyhow, so in this case we'll still end - // up using the extension even if wxCONFIG_USE_SUBDIR is not set, but this - // is the correct and expected (if a little confusing) behaviour. + // up using the extension even if neither wxCONFIG_USE_SUBDIR nor + // wxCONFIG_USE_XDG is set, but this is the correct and expected (if a + // little confusing) behaviour. const wxStandardPaths::ConfigFileConv - conv = style & wxCONFIG_USE_SUBDIR + conv = style & (wxCONFIG_USE_SUBDIR | wxCONFIG_USE_XDG) ? wxStandardPaths::ConfigFileConv_Ext : wxStandardPaths::ConfigFileConv_Dot; From b90747d61ad09c4742e2dc450e9834686cd708ad Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 2 Jan 2024 02:21:25 +0100 Subject: [PATCH 182/257] Use const references to wxStandardPaths in wxFileConfig code No real changes, just minor cleanup. --- src/common/fileconf.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index 08154612e3..494913275b 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -247,7 +247,7 @@ wxString wxFileConfig::GetGlobalDir() wxString wxFileConfig::GetLocalDir(int style) { - wxStandardPathsBase& stdp = wxStandardPaths::Get(); + const wxStandardPathsBase& stdp = wxStandardPaths::Get(); if ( style & wxCONFIG_USE_XDG ) { @@ -271,14 +271,14 @@ wxString wxFileConfig::GetLocalDir(int style) wxFileName wxFileConfig::GetGlobalFile(const wxString& szFile) { - wxStandardPathsBase& stdp = wxStandardPaths::Get(); + const wxStandardPathsBase& stdp = wxStandardPaths::Get(); return wxFileName(GetGlobalDir(), stdp.MakeConfigFileName(szFile)); } wxFileName wxFileConfig::GetLocalFile(const wxString& szFile, int style) { - wxStandardPathsBase& stdp = wxStandardPaths::Get(); + const wxStandardPathsBase& stdp = wxStandardPaths::Get(); // If the config file is located in a subdirectory, we always use an // extension for it, but we use just the leading dot if it is located From 989829891acd84a8dc2e33fdfe82d1946b517cfd Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 3 Jan 2024 18:36:25 +0100 Subject: [PATCH 183/257] Fix memory leak when calling wxInitialize(void) We still allocated argv arrays when argc was 0, but didn't free them in this case. Fix this by just not bothering to allocate them. --- src/common/init.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/common/init.cpp b/src/common/init.cpp index d3dd21fc00..919d9329f8 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -210,9 +210,9 @@ void wxInitData::InitIfNecessary(int argcIn, wchar_t** argvIn) // elsewhere, but it is also possible to call a wide-char initialization // function (wxInitialize(), wxEntryStart() or wxEntry() itself) directly, // so we need to support this case too. - if ( argc ) + if ( argc || !argcIn ) { - // Already initialized, nothing to do. + // Already initialized or nothing to do. return; } From 586e1b1d48cfed79d8287dc7e24e2b5c4445c6a5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 3 Jan 2024 18:43:30 +0100 Subject: [PATCH 184/257] Reuse existing variable in wxAuiNotebook::RemovePage() Don't call wxAuiTabCtrl::GetPageCount() again when we just stored its result in a local variable. No real changes. --- src/aui/auibook.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 035e763edb..bee3a5c003 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -2119,12 +2119,12 @@ bool wxAuiNotebook::RemovePage(size_t page_idx) if (is_active_in_split) { - int ctrl_new_page_count = (int)ctrl->GetPageCount(); + const int ctrl_new_page_count = (int)ctrl->GetPageCount(); if (ctrl_idx >= ctrl_new_page_count) ctrl_idx = ctrl_new_page_count-1; - if (ctrl_idx >= 0 && ctrl_idx < (int)ctrl->GetPageCount()) + if (ctrl_idx >= 0 && ctrl_idx < ctrl_new_page_count) { // set new page as active in the tab split ctrl->SetActivePage(ctrl_idx); From b66d0a640d913dec1f9a75f83a8b15fa0fd9407c Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 3 Jan 2024 18:58:23 +0100 Subject: [PATCH 185/257] Update new page in AUI tab control after removing the active one Previously this was only done when removing the global (i.e. per notebook) current page, but not when removing the page which was current in this tab control without being globally current, and this resulted in not showing the newly shown page correctly. Fix this by explicitly updating the tab control in this case. Closes #24063. --- src/aui/auibook.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index bee3a5c003..03d2c7dd3a 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -2136,6 +2136,16 @@ bool wxAuiNotebook::RemovePage(size_t page_idx) { new_active = ctrl->GetWindowFromIdx(ctrl_idx); } + else // not deleting the globally active page + { + // so don't change the current one + new_active = active_wnd; + + // but we still need to show the new active page in this + // control, otherwise it wouldn't be updated + ctrl->DoShowHide(); + ctrl->MakeTabVisible(ctrl_idx, ctrl); + } } } else From 3de2e479fce11c139663e2fc4252b65ed516f9fb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 3 Jan 2024 19:05:51 +0100 Subject: [PATCH 186/257] Add wxAuiTabCtrl::DoShowTab() helper No real changes, just add a function ensuring that the tab is shown. It's not really clear why the existing code sometimes calls MakeTabVisible() after SetActivePage() and sometimes doesn't, and perhaps it should actually always do it, in which case this function could be merged with SetActivePage() to do everything at once, but for now keep the changes minimal. --- include/wx/aui/auibook.h | 3 +++ src/aui/auibook.cpp | 13 ++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/wx/aui/auibook.h b/include/wx/aui/auibook.h index 8f79f8f576..67fae51ba7 100644 --- a/include/wx/aui/auibook.h +++ b/include/wx/aui/auibook.h @@ -210,6 +210,9 @@ public: void SetRect(const wxRect& rect) { wxAuiTabContainer::SetRect(rect, this); } + // Internal helper. + void DoShowTab(int idx); + protected: // choose the default border for this window virtual wxBorder GetDefaultBorder() const override { return wxBORDER_NONE; } diff --git a/src/aui/auibook.cpp b/src/aui/auibook.cpp index 03d2c7dd3a..326482ac17 100644 --- a/src/aui/auibook.cpp +++ b/src/aui/auibook.cpp @@ -1019,6 +1019,12 @@ wxAuiTabCtrl::~wxAuiTabCtrl() { } +void wxAuiTabCtrl::DoShowTab(int idx) +{ + DoShowHide(); + MakeTabVisible(idx, this); +} + void wxAuiTabCtrl::DoEndDragging() { m_clickPt = wxDefaultPosition; @@ -2143,8 +2149,7 @@ bool wxAuiNotebook::RemovePage(size_t page_idx) // but we still need to show the new active page in this // control, otherwise it wouldn't be updated - ctrl->DoShowHide(); - ctrl->MakeTabVisible(ctrl_idx, ctrl); + ctrl->DoShowTab(ctrl_idx); } } } @@ -3659,9 +3664,7 @@ int wxAuiNotebook::DoModifySelection(size_t n, bool events) ctrl->SetActivePage(ctrl_idx); DoSizing(); - ctrl->DoShowHide(); - - ctrl->MakeTabVisible(ctrl_idx, ctrl); + ctrl->DoShowTab(ctrl_idx); // set fonts wxAuiPaneInfoArray& all_panes = m_mgr.GetAllPanes(); From 261490d5e2f7b5ec1c76824436cf851515156a99 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 3 Jan 2024 20:21:59 +0100 Subject: [PATCH 187/257] Ignore failures in tests handling mouse clicks under AppVeyor For some completely mysterious reason we don't get the expected mouse click events when running under AppVeyor, something might be covering the window and stealing the clicks for itself there. As there doesn't seem to be anything to do about it, just skip the test in this case. Closes #24082. --- tests/controls/gridtest.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index a77f2ad39d..485f430d03 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -221,6 +221,17 @@ WaitForEventAt( if ( sw.Time() > timeout ) { + // This sporadically happens under AppVeyor for unknown reasons and + // there doesn't seem to be anything we can do about it, so just + // skip the test if it happens. + if ( IsAutomaticTest() ) + { + WARN("Timed out waiting for " << what << "; skipping test"); + return false; + } + + // Otherwise fail it -- maybe someone will be able to understand + // why it happens one day if it does happen locally. FAIL("Timed out waiting for " << what); break; // unreachable } From a8b14edc4072d82eae2a477c2168d0b982b9526b Mon Sep 17 00:00:00 2001 From: David Miguel Susano Pinto Date: Wed, 3 Jan 2024 17:55:41 +0000 Subject: [PATCH 188/257] Correct wxRealPoint and wxPoint operator return types in the docs Use the correct types instead of wxSize which was erroneously used there ever since a5664fd6ef (Increase interoperability between wxPoint and wxRealPoint introducing constructors which convert between the two classes., 2010-06-09). Closes #23804. --- interface/wx/gdicmn.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index c512a99a3b..5f2a3b5c48 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -227,11 +227,11 @@ public: wxRealPoint& operator +=(const wxSize& sz); wxRealPoint& operator -=(const wxSize& sz); - wxSize operator /(const wxRealPoint& sz, int factor); - wxSize operator *(const wxRealPoint& sz, int factor); - wxSize operator *(int factor, const wxSize& sz); - wxSize& operator /=(int factor); - wxSize& operator *=(int factor); + wxRealPoint operator /(const wxRealPoint& sz, int factor); + wxRealPoint operator *(const wxRealPoint& sz, int factor); + wxRealPoint operator *(int factor, const wxRealPoint& sz); + wxRealPoint& operator /=(int factor); + wxRealPoint& operator *=(int factor); ///@} /** @@ -731,11 +731,11 @@ public: wxPoint& operator +=(const wxSize& sz); wxPoint& operator -=(const wxSize& sz); - wxSize operator /(const wxPoint& sz, int factor); - wxSize operator *(const wxPoint& sz, int factor); - wxSize operator *(int factor, const wxSize& sz); - wxSize& operator /=(int factor); - wxSize& operator *=(int factor); + wxPoint operator /(const wxPoint& sz, int factor); + wxPoint operator *(const wxPoint& sz, int factor); + wxPoint operator *(int factor, const wxPoint& sz); + wxPoint& operator /=(int factor); + wxPoint& operator *=(int factor); ///@} From 055c4cbed5006f801d6e01a88eea46d89a67dc39 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 4 Jan 2024 02:46:18 +0100 Subject: [PATCH 189/257] Fix crash on shutdown if wxConfig couldn't be saved If saving wxConfig to the file in wxAppConsoleBase::CleanUp() failed, wxLog messages were logged into a wxLogGui target which was recreated because wxTheApp is still non-null when CleanUp() is called. However it is destroyed soon afterwards and showing messages from wxLogGui without wxTheApp leads to crashes, at least in wxGTK. To avoid this, we could set wxTheApp to null before calling CleanUp(), but it's not clear if there is no cleanup code (or something called from it) which doesn't rely on wxTheApp existence, so instead just flush, and reset, the log target after calling CleanUp() but before destroying the application object. This fixes the crash which could be easily reproduced simply by making the file used by wxFileConfig not-writeable under Linux. --- src/common/init.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/common/init.cpp b/src/common/init.cpp index d3dd21fc00..7c7330e4f3 100644 --- a/src/common/init.cpp +++ b/src/common/init.cpp @@ -488,14 +488,18 @@ static void DoCommonPostCleanup() void wxEntryCleanup() { - DoCommonPreCleanup(); - - // delete the application object if ( wxTheApp ) { wxTheApp->CleanUp(); + } + // It's important to call this after wxApp::CleanUp() as it can log some + // messages that will be flushed inside DoCommonPreCleanup(). + DoCommonPreCleanup(); + + if ( wxTheApp ) + { // reset the global pointer to it to nullptr before destroying it as in // some circumstances this can result in executing the code using // wxTheApp and using half-destroyed object is no good From ebe0847932dad995ff7f0e7cd6cf5cc6361f9fc7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 4 Jan 2024 02:53:23 +0100 Subject: [PATCH 190/257] Add wxHAS_CONFIG_AS_{REG,FILE}CONFIG symbols Sometimes it's useful to have some code used only if wxConfig is defined as wxRegConfig or only if it is defined as wxFileConfig and testing for these symbols is more clear than testing for the platform (and more correct, considering that setting wxUSE_CONFIG_NATIVE to 0 may result in wxFileConfig being used even under Windows). --- docs/doxygen/mainpages/const_cpp.h | 4 ++++ include/wx/config.h | 2 ++ interface/wx/config.h | 4 +++- src/common/config.cpp | 13 +++++++------ 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/docs/doxygen/mainpages/const_cpp.h b/docs/doxygen/mainpages/const_cpp.h index 9c982c3323..5a1df738de 100644 --- a/docs/doxygen/mainpages/const_cpp.h +++ b/docs/doxygen/mainpages/const_cpp.h @@ -168,6 +168,10 @@ Currently the following symbols exist: implemented in a generic way, using a critical section.} @itemdef{wxHAS_BITMAPTOGGLEBUTTON, Defined in @c wx/tglbtn.h if wxBitmapToggleButton class is available in addition to wxToggleButton.} +@itemdef{wxHAS_CONFIG_AS_FILECONFIG, Defined if wxConfig is defined as + wxFileConfig. This constant is available since wxWidgets 3.3.0.} +@itemdef{wxHAS_CONFIG_AS_REGCONFIG, Defined if wxConfig is defined as + wxRegConfig. This constant is available since wxWidgets 3.3.0.} @itemdef{wxHAS_CONFIG_TEMPLATE_RW, Defined if the currently used compiler supports template Read() and Write() methods in wxConfig.} @itemdef{wxHAS_DEPRECATED_ATTR, Defined if C++14 @c [[deprecated]] attribute is diff --git a/include/wx/config.h b/include/wx/config.h index 177665116d..9a47bdedb4 100644 --- a/include/wx/config.h +++ b/include/wx/config.h @@ -23,9 +23,11 @@ #if defined(__WINDOWS__) && wxUSE_CONFIG_NATIVE #include "wx/msw/regconf.h" #define wxConfig wxRegConfig + #define wxHAS_CONFIG_AS_REGCONFIG #else // either we're under Unix or wish to always use config files #include "wx/fileconf.h" #define wxConfig wxFileConfig + #define wxHAS_CONFIG_AS_FILECONFIG #endif #endif // wxUSE_CONFIG diff --git a/interface/wx/config.h b/interface/wx/config.h index 3e86aa9434..3be4368c66 100644 --- a/interface/wx/config.h +++ b/interface/wx/config.h @@ -57,7 +57,9 @@ enum with the registry under Windows or text-based config files under Unix. To make writing the portable code even easier, wxWidgets provides a typedef wxConfig which is mapped onto the native wxConfigBase implementation on the - given platform: i.e. wxRegConfig under Windows and wxFileConfig otherwise. + given platform: i.e. wxRegConfig under Windows (in this case + `wxHAS_CONFIG_AS_REGCONFIG` preprocessor symbol is defined) and + wxFileConfig otherwise (in this case `wxHAS_CONFIG_AS_FILECONFIG` is). See @ref overview_config for a description of all features of this class. diff --git a/src/common/config.cpp b/src/common/config.cpp index fb29b8538d..7a2765636f 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -56,12 +56,13 @@ bool wxConfigBase::ms_bAutoCreate = true; wxConfigBase *wxAppTraitsBase::CreateConfig() { - return new - #if defined(__WINDOWS__) && wxUSE_CONFIG_NATIVE - wxRegConfig(wxTheApp->GetAppName(), wxTheApp->GetVendorName()); - #else // either we're under Unix or wish to use files even under Windows - wxFileConfig(wxTheApp->GetAppName()); - #endif +#if defined(wxHAS_CONFIG_AS_REGCONFIG) + return new wxRegConfig(wxTheApp->GetAppName(), wxTheApp->GetVendorName()); +#elif defined(wxHAS_CONFIG_AS_FILECONFIG) + return new wxFileConfig(wxTheApp->GetAppName()); +#else + #error No wxConfig implementation defined. +#endif } // ---------------------------------------------------------------------------- From 486865b4462d149b40ee2eba3d66e86b7f4b3fab Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 4 Jan 2024 03:05:44 +0100 Subject: [PATCH 191/257] Add wxFileConfig::MigrateLocalFile() This can be useful for the existing applications switching to using XDG-compliant config files location as they can just call this function on startup to keep using the existing file. --- include/wx/fileconf.h | 16 ++++++ interface/wx/fileconf.h | 67 ++++++++++++++++++++++++- samples/widgets/widgets.cpp | 27 ++++++++++ src/common/fileconf.cpp | 99 +++++++++++++++++++++++++++++++++++++ 4 files changed, 208 insertions(+), 1 deletion(-) diff --git a/include/wx/fileconf.h b/include/wx/fileconf.h index 87f698a38f..4229820cf8 100644 --- a/include/wx/fileconf.h +++ b/include/wx/fileconf.h @@ -123,6 +123,22 @@ public: return GetLocalFile(szFile, style).GetFullPath(); } + // Function to migrate, i.e. move, an existing local config file to another + // location. Old and new style determine the existing and new file paths. + struct MigrationResult + { + // If empty, it means the old file wasn't found and nothing was done. + wxString oldPath; + + // The name of the new file. + wxString newPath; + + // If empty, means the file was successfully migrated. + wxString error; + }; + static MigrationResult + MigrateLocalFile(const wxString& name, int newStyle, int oldStyle = 0); + // ctor & dtor // New constructor: one size fits all. Specify wxCONFIG_USE_LOCAL_FILE or // wxCONFIG_USE_GLOBAL_FILE to say which files should be used. diff --git a/interface/wx/fileconf.h b/interface/wx/fileconf.h index ae91b8e481..05f3c14b21 100644 --- a/interface/wx/fileconf.h +++ b/interface/wx/fileconf.h @@ -25,7 +25,8 @@ path is backwards-compatible but not recommended any more and it is advised to call wxStandardPaths::SetFileLayout() with wxStandardPaths::FileLayout_XDG parameter to change the default path to - `~/.config/appname.conf`. + `~/.config/appname.conf`. MigrateLocalFile() may be helpful for moving the + existing configuration file to the new location. Alternatively, it is possible to specify ::wxCONFIG_USE_XDG flag in the style parameter of the constructor to use this XDG-compliant path without @@ -99,6 +100,70 @@ public: static wxString GetGlobalFileName(const wxString& szFile); static wxString GetLocalFileName(const wxString& szFile, int style = 0); + /** + Contains return value of MigrateLocalFile(). + + @since 3.3.0 + */ + struct MigrationResult + { + /// If empty, it means the old file wasn't found and nothing was done. + wxString oldPath; + + /// The name of the new file. + wxString newPath; + + /// If empty, means the file was successfully migrated. + wxString error; + }; + + /** + Move the existing configuration file to a new location. + + This function is useful for moving legacy configuration files in + `~/.appname` or `~/.appname/appname.conf` to the XDG-compliant location + under `~/.config`. To do this, simply specify ::wxCONFIG_USE_XDG as + part of @a newStyle. + + The returned MigrationResult object describes what, if anything, was + done: if its `oldPath` member is empty, it means that the file + corresponding to @a oldStyle was not found and nothing was done. + Otherwise, if its `error` member is empty, the old file was found and + moved to `newPath`. And if `error` is not empty, it contains the + user-readable error message describing why moving the file failed. + + Typical example of using this function is shown in the widgets sample: + @code + // Execute this early during the application startup, before the + // global wxConfig object is created. + const auto res = wxFileConfig::MigrateLocalFile("app", wxCONFIG_USE_XDG); + if ( !res.oldPath.empty() ) { + if ( res.error.empty() ) { + wxLogMessage("Config file was migrated from \"%s\" to \"%s\"", + res.oldPath, res.newPath); + } else { + wxLogWarning("Migrating old config failed: %s.", res.error); + } + } + + // Note that this must be done after calling MigrateLocalFile(), + // otherwise the old style would use XDG layout already and the actual + // file at non-XDG-compliant location wouldn't be migrated. + wxStandardPaths::Get().SetFileLayout(wxStandardPaths::FileLayout_XDG); + @endcode + + @param name Name of the configuration file. + @param newStyle Style which is used by the current version of the + program, typically including ::wxCONFIG_USE_XDG and possibly also + including ::wxCONFIG_USE_SUBDIR. + @param oldStyle Style which was used by the previous versions of the + program, possibly including ::wxCONFIG_USE_SUBDIR. + + @since 3.3.0 + */ + static MigrationResult + MigrateLocalFile(const wxString& name, int newStyle, int oldStyle = 0); + /** Saves all config data to the given stream, returns @true if data was saved successfully or @false on error. diff --git a/samples/widgets/widgets.cpp b/samples/widgets/widgets.cpp index 263e8ddac5..9add0d857d 100644 --- a/samples/widgets/widgets.cpp +++ b/samples/widgets/widgets.cpp @@ -37,6 +37,9 @@ #include "wx/msgdlg.h" #endif +#include "wx/config.h" +#include "wx/stdpaths.h" + #include "wx/sysopt.h" #include "wx/bookctrl.h" #include "wx/treebook.h" @@ -141,6 +144,30 @@ public: #if USE_LOG m_logTarget = nullptr; #endif // USE_LOG + +#ifdef wxHAS_CONFIG_AS_FILECONFIG + // We want to put our config file (implicitly created for persistent + // controls settings) in XDG-compliant location, so we want to change + // the default file layout, but before doing this migrate any existing + // config files to the new location as the previous versions of this + // sample didn't use XDG layout. + const auto + res = wxFileConfig::MigrateLocalFile("widgets", wxCONFIG_USE_XDG); + if ( !res.oldPath.empty() ) + { + if ( res.error.empty() ) + { + wxLogMessage("Config file was migrated from \"%s\" to \"%s\"", + res.oldPath, res.newPath); + } + else + { + wxLogWarning("Migrating old config failed: %s.", res.error); + } + } + + wxStandardPaths::Get().SetFileLayout(wxStandardPaths::FileLayout_XDG); +#endif // wxHAS_CONFIG_AS_FILECONFIG } WidgetsApp(const WidgetsApp&) = delete; WidgetsApp& operator=(const WidgetsApp&) = delete; diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index 494913275b..17e6b6469e 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -296,6 +296,105 @@ wxFileName wxFileConfig::GetLocalFile(const wxString& szFile, int style) return wxFileName(GetLocalDir(style), stdp.MakeConfigFileName(szFile, conv)); } +wxFileConfig::MigrationResult +wxFileConfig::MigrateLocalFile(const wxString& name, int newStyle, int oldStyle) +{ + MigrationResult res; + + const auto oldPath = GetLocalFile(name, oldStyle); + if ( !oldPath.FileExists() ) + return res; + + const auto newPath = GetLocalFile(name, newStyle); + if ( newPath == oldPath ) + return res; + + res.oldPath = oldPath.GetFullPath(); + res.newPath = newPath.GetFullPath(); + + // This class ensures that we (at least try to) rename the existing config + // file back to its original name if we fail with an error. + class RenameBackOnError + { + public: + explicit RenameBackOnError(wxFileConfig::MigrationResult& res) + : m_res(res) + { + } + + void Init(const wxString& tempPath) + { + m_tempPath = tempPath; + } + + void Dismiss() + { + m_tempPath.clear(); + } + + ~RenameBackOnError() + { + if ( !m_tempPath.empty() ) + { + if ( !wxRenameFile(m_tempPath, m_res.oldPath) ) + { + // This should never happen, but if it does, do at least + // let the user know that we moved their file to a wrong + // place and couldn't put it back. + m_res.error += wxString::Format( + _(" and additionally, the existing configuration file" + " was renamed to \"%s\" and couldn't be renamed back," + " please rename it to its original path \"%s\""), + m_tempPath, + m_res.oldPath + ); + } + } + } + + private: + MigrationResult& m_res; + + wxString m_tempPath; + } renameBackOnError{res}; + + wxString currentPath = res.oldPath; + + const auto newDir = newPath.GetPath(); + if ( !wxFileName::DirExists(newDir) ) + { + // There is an annoying failure mode here when the new directory can't + // be created because its name is the same as the name of the existing + // file, e.g. when oldStyle==0 and newStyle==wxCONFIG_USE_SUBDIR and + // XDG layout is not used, so check for this specially. + if ( newDir == res.oldPath ) + { + currentPath = wxFileName::CreateTempFileName(currentPath); + if ( !wxRenameFile(res.oldPath, currentPath) ) + { + res.error = _("failed to rename the existing file"); + return res; + } + + renameBackOnError.Init(currentPath); + } + + if ( !wxFileName::Mkdir(newDir, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) ) + { + res.error = _("failed to create the new file directory"); + return res; + } + } + + if ( !wxRenameFile(currentPath, res.newPath) ) + { + res.error = _("failed to move the file to the new location"); + return res; + } + + return res; +} + // ---------------------------------------------------------------------------- // ctor // ---------------------------------------------------------------------------- From 5faa70503a9c9152d1caba6a2c805ebe911e12a9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 4 Jan 2024 03:25:07 +0100 Subject: [PATCH 192/257] Fix name in the comment for wx_check_c_source_compiles() No real changes. --- build/cmake/setup.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/cmake/setup.cmake b/build/cmake/setup.cmake index 297a251f28..89976aecb0 100644 --- a/build/cmake/setup.cmake +++ b/build/cmake/setup.cmake @@ -110,7 +110,7 @@ function(wx_check_cxx_source_compiles code res_var) cmake_pop_check_state() endfunction() -# wx_check_cxx_source_compiles( [headers...]) +# wx_check_c_source_compiles( [headers...]) function(wx_check_c_source_compiles code res_var) set(src) foreach(header ${ARGN}) From 31a672b858f5a30548a4f236eb06146b582ea5ce Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 4 Jan 2024 12:11:50 -0800 Subject: [PATCH 193/257] Improve our best size calculation for multi-line wxTextCtrl with GTK Instead of trying to figure it out ourselves, just ask the control what its minimum size is. --- src/gtk/textctrl.cpp | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/src/gtk/textctrl.cpp b/src/gtk/textctrl.cpp index 6fad82910c..bcfd30895b 100644 --- a/src/gtk/textctrl.cpp +++ b/src/gtk/textctrl.cpp @@ -2153,24 +2153,13 @@ wxSize wxTextCtrl::DoGetSizeFromTextSize(int xlen, int ylen) const //multiline else { - // add space for vertical scrollbar - if ( m_scrollBar[1] && !(m_windowStyle & wxTE_NO_VSCROLL) ) - tsize.IncBy(GTKGetPreferredSize(GTK_WIDGET(m_scrollBar[1])).x + 3, 0); - // height if ( ylen <= 0 ) - { tsize.y = 1 + cHeight * wxMax(wxMin(GetNumberOfLines(), 10), 2); - // add space for horizontal scrollbar - if ( m_scrollBar[0] && (m_windowStyle & wxHSCROLL) ) - tsize.IncBy(0, GTKGetPreferredSize(GTK_WIDGET(m_scrollBar[0])).y + 3); - } - if ( !HasFlag(wxBORDER_NONE) ) - { - // hardcode borders, margins, etc - tsize.IncBy(5, 4); - } + GtkRequisition req; + gtk_widget_get_preferred_size(m_widget, &req, nullptr); + tsize.IncTo(wxSize(req.width, req.height)); } // We should always use at least the specified height if it's valid. From cd93c739004b11883709cefb37c347b1f4975a43 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 4 Jan 2024 12:22:39 -0800 Subject: [PATCH 194/257] Remove another reference to GLU Should have been part of ce1d317768 (Remove GLU dependency, 2023-12-28) --- include/wx/setup_inc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/wx/setup_inc.h b/include/wx/setup_inc.h index acfb068814..f6200c70f4 100644 --- a/include/wx/setup_inc.h +++ b/include/wx/setup_inc.h @@ -1323,7 +1323,7 @@ // Setting wxUSE_GLCANVAS to 1 enables OpenGL support. You need to have OpenGL // headers and libraries to be able to compile the library with wxUSE_GLCANVAS -// set to 1 and, under Windows, also to add opengl32.lib and glu32.lib to the +// set to 1 and, under Windows, also to add opengl32.lib to the // list of libraries used to link your application when linking to wxWidgets // statically (although this is done implicitly for Microsoft Visual C++ users). // From 071e3187f50e4295d98408a2c826ac1e635abeef Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 4 Jan 2024 12:34:56 -0800 Subject: [PATCH 195/257] Remove unused variables These have been unused since e95354ec54 (added UTF-16/32-[LB]E conversions; got rid of wxCharacterSet and simplified and fixed some bugs in remaining code, 2003-09-22) --- src/common/strconv.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index edc549d301..4fbc018ca2 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -1753,10 +1753,6 @@ wxMBConvUTF16swap::FromWChar(char *dst, size_t dstLen, #define wxMBConvUTF32straight wxMBConvUTF32LE #endif - -WXDLLIMPEXP_DATA_BASE(wxMBConvUTF32LE) wxConvUTF32LE; -WXDLLIMPEXP_DATA_BASE(wxMBConvUTF32BE) wxConvUTF32BE; - /* static */ size_t wxMBConvUTF32Base::GetLength(const char *src, size_t srcLen) { From a5e9befd4d3add8afca6d48fd7666c09f82d0961 Mon Sep 17 00:00:00 2001 From: Paul Cornett Date: Thu, 4 Jan 2024 12:49:37 -0800 Subject: [PATCH 196/257] Remove unused class Unused since 025f5d1450 (Don't cache HDC used by wxPaintDCEx in wxMSW., 2013-03-09) --- src/msw/dcclient.cpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/msw/dcclient.cpp b/src/msw/dcclient.cpp index cf956ef7d5..cc2549ca7c 100644 --- a/src/msw/dcclient.cpp +++ b/src/msw/dcclient.cpp @@ -95,28 +95,6 @@ private: wxDECLARE_NO_COPY_CLASS(wxPaintDCInfoOur); }; -// This subclass contains information for the HDCs we receive from outside, as -// WPARAM of WM_PAINT itself. -class wxPaintDCInfoExternal : public wxPaintDCInfo -{ -public: - wxPaintDCInfoExternal(HDC hdc) - : wxPaintDCInfo(hdc), - m_state(::SaveDC(hdc)) - { - } - - virtual ~wxPaintDCInfoExternal() - { - ::RestoreDC(m_hdc, m_state); - } - -private: - const int m_state; - - wxDECLARE_NO_COPY_CLASS(wxPaintDCInfoExternal); -}; - // The global map containing HDC to use for the given window. The entries in // this map only exist during WM_PAINT processing and are destroyed when it is // over. From 11ebffe7b09d42ff62485d2304ffc20654616e38 Mon Sep 17 00:00:00 2001 From: David Miguel Susano Pinto Date: Wed, 3 Jan 2024 21:19:01 +0000 Subject: [PATCH 197/257] Add operator/(wxPoint, double) and operator/(wxRealPoint, double) Do this for consistency with wxSize which already had this operator/() overload and operator*() in these classes which was already overloaded for double. Closes #24185. Closes #24187. --- include/wx/gdicmn.h | 10 ++++++++++ interface/wx/gdicmn.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 30a54326c2..ae0287ac8d 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -564,6 +564,11 @@ inline wxRealPoint operator*(double i, const wxRealPoint& s) return wxRealPoint(s.x * i, s.y * i); } +inline wxRealPoint operator/(const wxRealPoint& p, double f) +{ + return wxRealPoint(p.x / f, p.y / f); +} + // ---------------------------------------------------------------------------- // wxPoint: 2D point with integer coordinates @@ -719,6 +724,11 @@ inline wxPoint operator*(double i, const wxPoint& s) return wxPoint(int(s.x * i), int(s.y * i)); } +inline wxPoint operator/(const wxPoint& p, double f) +{ + return wxPoint(wxRound(p.x / f), wxRound(p.y / f)); +} + WX_DECLARE_LIST_WITH_DECL(wxPoint, wxPointList, class WXDLLIMPEXP_CORE); // --------------------------------------------------------------------------- diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index 5f2a3b5c48..53fcc348dc 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -232,6 +232,8 @@ public: wxRealPoint operator *(int factor, const wxRealPoint& sz); wxRealPoint& operator /=(int factor); wxRealPoint& operator *=(int factor); + + wxRealPoint operator /(const wxRealPoint& pt, double factor); ///@} /** @@ -736,6 +738,8 @@ public: wxPoint operator *(int factor, const wxPoint& sz); wxPoint& operator /=(int factor); wxPoint& operator *=(int factor); + + wxPoint operator /(const wxPoint& pt, double factor); ///@} From 3dde6bdeb0cec5af8b81a231b9deb851d975a2c2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 25 Dec 2023 21:42:07 +0100 Subject: [PATCH 198/257] Disable swap interval in GLX wxGLCanvas implementation too We need to do it when using XWayland for the same reasons as we had to do it in the EGL version when using either XWayland or Wayland directly: without this, we can block for up to 1 second in glXSwapBuffers() if the window is hidden, see #23512. Closes #24163. Closes #24165. --- include/wx/unix/glx11.h | 2 ++ src/unix/glx11.cpp | 56 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/include/wx/unix/glx11.h b/include/wx/unix/glx11.h index b0e4c89cf9..cad490a878 100644 --- a/include/wx/unix/glx11.h +++ b/include/wx/unix/glx11.h @@ -99,6 +99,8 @@ public: private: GLXFBConfig *m_fbc; void* m_vi; + + bool m_swapIntervalSet = false; }; // ---------------------------------------------------------------------------- diff --git a/src/unix/glx11.cpp b/src/unix/glx11.cpp index fa73d16557..83cba2ba17 100644 --- a/src/unix/glx11.cpp +++ b/src/unix/glx11.cpp @@ -124,6 +124,13 @@ typedef GLXContext(*PFNGLXCREATECONTEXTATTRIBSARBPROC) #define GLX_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 #endif +namespace +{ + +constexpr const char* TRACE_GLX = "glx"; + +} // anonymous namespace + // ---------------------------------------------------------------------------- // wxGLContextAttrs: OpenGL rendering context attributes // ---------------------------------------------------------------------------- @@ -762,12 +769,59 @@ int wxGLCanvasX11::GetGLXVersion() return s_glxVersion; } +namespace +{ + +// Call glXSwapIntervalEXT() if present. +// +// For now just try using EXT_swap_control extension, in principle there is +// also a MESA one, but it's not clear if it's worth falling back on it (or +// preferring to use it?). +void wxGLSetSwapInterval(Display* dpy, GLXDrawable drawable, int interval) +{ + typedef void (*PFNGLXSWAPINTERVALEXTPROC)(Display *dpy, + GLXDrawable drawable, + int interval); + + static PFNGLXSWAPINTERVALEXTPROC s_glXSwapIntervalEXT = nullptr; + static bool s_glXSwapIntervalEXTInit = false; + if ( !s_glXSwapIntervalEXTInit ) + { + s_glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) + glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT"); + + s_glXSwapIntervalEXTInit = true; + } + + if ( s_glXSwapIntervalEXT ) + { + wxLogTrace(TRACE_GLX, "Setting GLX swap interval to %d", interval); + + s_glXSwapIntervalEXT(dpy, drawable, interval); + } +} + +} // anonymous namespace + bool wxGLCanvasX11::SwapBuffers() { const Window xid = GetXWindow(); wxCHECK2_MSG( xid, return false, wxT("window must be shown") ); - glXSwapBuffers(wxGetX11Display(), xid); + const auto dpy = wxGetX11Display(); + + // Disable blocking in glXSwapBuffers, as this is needed under XWayland for + // the reasons explained in wxGLCanvasEGL::SwapBuffers(). + if ( !m_swapIntervalSet ) + { + wxGLSetSwapInterval(dpy, xid, 0); + + // Don't try again in any case, if we failed this time, we'll fail the + // next one anyhow. + m_swapIntervalSet = true; + } + + glXSwapBuffers(dpy, xid); return true; } From 9a5d2ffade725241564de22a849ca726a4689950 Mon Sep 17 00:00:00 2001 From: David Miguel Susano Pinto Date: Thu, 4 Jan 2024 00:19:35 +0000 Subject: [PATCH 199/257] Correct names of variables in wxPoint and wxRealPoint arithmetic operators. The arithmetic operators for wxPoint and wxRealPoint are quite repetitive and were made by copy-paste from the wxSize operators. Because of that, some of the names are a bit misleading which this commit changes. The changes are: 1. replace s/sz with p/pt for point variables (likely 's' comes from copied code used for wxSize variables) 2. replace 'i' with 'f' for floating point types (likely 'i' comes from copied code used for integer types) 3. replace 'factor' with 'divisor' for division operations (factors are the multiplication operands, not division) --- include/wx/gdicmn.h | 112 +++++++++++++++++++++--------------------- interface/wx/gdicmn.h | 14 +++--- 2 files changed, 63 insertions(+), 63 deletions(-) diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index ae0287ac8d..5467575e2c 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -494,74 +494,74 @@ inline wxRealPoint operator-(const wxRealPoint& p1, const wxRealPoint& p2) } -inline wxRealPoint operator/(const wxRealPoint& s, int i) +inline wxRealPoint operator/(const wxRealPoint& p, int i) { - return wxRealPoint(s.x / i, s.y / i); + return wxRealPoint(p.x / i, p.y / i); } -inline wxRealPoint operator*(const wxRealPoint& s, int i) +inline wxRealPoint operator*(const wxRealPoint& p, int i) { - return wxRealPoint(s.x * i, s.y * i); + return wxRealPoint(p.x * i, p.y * i); } -inline wxRealPoint operator*(int i, const wxRealPoint& s) +inline wxRealPoint operator*(int i, const wxRealPoint& p) { - return wxRealPoint(s.x * i, s.y * i); + return wxRealPoint(p.x * i, p.y * i); } -inline wxRealPoint operator/(const wxRealPoint& s, unsigned int i) +inline wxRealPoint operator/(const wxRealPoint& p, unsigned int i) { - return wxRealPoint(s.x / i, s.y / i); + return wxRealPoint(p.x / i, p.y / i); } -inline wxRealPoint operator*(const wxRealPoint& s, unsigned int i) +inline wxRealPoint operator*(const wxRealPoint& p, unsigned int i) { - return wxRealPoint(s.x * i, s.y * i); + return wxRealPoint(p.x * i, p.y * i); } -inline wxRealPoint operator*(unsigned int i, const wxRealPoint& s) +inline wxRealPoint operator*(unsigned int i, const wxRealPoint& p) { - return wxRealPoint(s.x * i, s.y * i); + return wxRealPoint(p.x * i, p.y * i); } -inline wxRealPoint operator/(const wxRealPoint& s, long i) +inline wxRealPoint operator/(const wxRealPoint& p, long i) { - return wxRealPoint(s.x / i, s.y / i); + return wxRealPoint(p.x / i, p.y / i); } -inline wxRealPoint operator*(const wxRealPoint& s, long i) +inline wxRealPoint operator*(const wxRealPoint& p, long i) { - return wxRealPoint(s.x * i, s.y * i); + return wxRealPoint(p.x * i, p.y * i); } -inline wxRealPoint operator*(long i, const wxRealPoint& s) +inline wxRealPoint operator*(long i, const wxRealPoint& p) { - return wxRealPoint(s.x * i, s.y * i); + return wxRealPoint(p.x * i, p.y * i); } -inline wxRealPoint operator/(const wxRealPoint& s, unsigned long i) +inline wxRealPoint operator/(const wxRealPoint& p, unsigned long i) { - return wxRealPoint(s.x / i, s.y / i); + return wxRealPoint(p.x / i, p.y / i); } -inline wxRealPoint operator*(const wxRealPoint& s, unsigned long i) +inline wxRealPoint operator*(const wxRealPoint& p, unsigned long i) { - return wxRealPoint(s.x * i, s.y * i); + return wxRealPoint(p.x * i, p.y * i); } -inline wxRealPoint operator*(unsigned long i, const wxRealPoint& s) +inline wxRealPoint operator*(unsigned long i, const wxRealPoint& p) { - return wxRealPoint(s.x * i, s.y * i); + return wxRealPoint(p.x * i, p.y * i); } -inline wxRealPoint operator*(const wxRealPoint& s, double i) +inline wxRealPoint operator*(const wxRealPoint& p, double f) { - return wxRealPoint(s.x * i, s.y * i); + return wxRealPoint(p.x * f, p.y * f); } -inline wxRealPoint operator*(double i, const wxRealPoint& s) +inline wxRealPoint operator*(double f, const wxRealPoint& p) { - return wxRealPoint(s.x * i, s.y * i); + return wxRealPoint(p.x * f, p.y * f); } inline wxRealPoint operator/(const wxRealPoint& p, double f) @@ -654,74 +654,74 @@ inline wxPoint operator-(const wxPoint& p) return wxPoint(-p.x, -p.y); } -inline wxPoint operator/(const wxPoint& s, int i) +inline wxPoint operator/(const wxPoint& p, int i) { - return wxPoint(s.x / i, s.y / i); + return wxPoint(p.x / i, p.y / i); } -inline wxPoint operator*(const wxPoint& s, int i) +inline wxPoint operator*(const wxPoint& p, int i) { - return wxPoint(s.x * i, s.y * i); + return wxPoint(p.x * i, p.y * i); } -inline wxPoint operator*(int i, const wxPoint& s) +inline wxPoint operator*(int i, const wxPoint& p) { - return wxPoint(s.x * i, s.y * i); + return wxPoint(p.x * i, p.y * i); } -inline wxPoint operator/(const wxPoint& s, unsigned int i) +inline wxPoint operator/(const wxPoint& p, unsigned int i) { - return wxPoint(s.x / i, s.y / i); + return wxPoint(p.x / i, p.y / i); } -inline wxPoint operator*(const wxPoint& s, unsigned int i) +inline wxPoint operator*(const wxPoint& p, unsigned int i) { - return wxPoint(s.x * i, s.y * i); + return wxPoint(p.x * i, p.y * i); } -inline wxPoint operator*(unsigned int i, const wxPoint& s) +inline wxPoint operator*(unsigned int i, const wxPoint& p) { - return wxPoint(s.x * i, s.y * i); + return wxPoint(p.x * i, p.y * i); } -inline wxPoint operator/(const wxPoint& s, long i) +inline wxPoint operator/(const wxPoint& p, long i) { - return wxPoint(s.x / i, s.y / i); + return wxPoint(p.x / i, p.y / i); } -inline wxPoint operator*(const wxPoint& s, long i) +inline wxPoint operator*(const wxPoint& p, long i) { - return wxPoint(int(s.x * i), int(s.y * i)); + return wxPoint(int(p.x * i), int(p.y * i)); } -inline wxPoint operator*(long i, const wxPoint& s) +inline wxPoint operator*(long i, const wxPoint& p) { - return wxPoint(int(s.x * i), int(s.y * i)); + return wxPoint(int(p.x * i), int(p.y * i)); } -inline wxPoint operator/(const wxPoint& s, unsigned long i) +inline wxPoint operator/(const wxPoint& p, unsigned long i) { - return wxPoint(s.x / i, s.y / i); + return wxPoint(p.x / i, p.y / i); } -inline wxPoint operator*(const wxPoint& s, unsigned long i) +inline wxPoint operator*(const wxPoint& p, unsigned long i) { - return wxPoint(int(s.x * i), int(s.y * i)); + return wxPoint(int(p.x * i), int(p.y * i)); } -inline wxPoint operator*(unsigned long i, const wxPoint& s) +inline wxPoint operator*(unsigned long i, const wxPoint& p) { - return wxPoint(int(s.x * i), int(s.y * i)); + return wxPoint(int(p.x * i), int(p.y * i)); } -inline wxPoint operator*(const wxPoint& s, double i) +inline wxPoint operator*(const wxPoint& p, double f) { - return wxPoint(int(s.x * i), int(s.y * i)); + return wxPoint(int(p.x * f), int(p.y * f)); } -inline wxPoint operator*(double i, const wxPoint& s) +inline wxPoint operator*(double f, const wxPoint& p) { - return wxPoint(int(s.x * i), int(s.y * i)); + return wxPoint(int(p.x * f), int(p.y * f)); } inline wxPoint operator/(const wxPoint& p, double f) diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index 53fcc348dc..9305d54a31 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -227,13 +227,13 @@ public: wxRealPoint& operator +=(const wxSize& sz); wxRealPoint& operator -=(const wxSize& sz); - wxRealPoint operator /(const wxRealPoint& sz, int factor); + wxRealPoint operator /(const wxRealPoint& sz, int divisor); wxRealPoint operator *(const wxRealPoint& sz, int factor); - wxRealPoint operator *(int factor, const wxRealPoint& sz); - wxRealPoint& operator /=(int factor); + wxRealPoint operator *(int factor, const wxRealPoint& pt); + wxRealPoint& operator /=(int divisor); wxRealPoint& operator *=(int factor); - wxRealPoint operator /(const wxRealPoint& pt, double factor); + wxRealPoint operator /(const wxRealPoint& pt, double divisor); ///@} /** @@ -733,13 +733,13 @@ public: wxPoint& operator +=(const wxSize& sz); wxPoint& operator -=(const wxSize& sz); - wxPoint operator /(const wxPoint& sz, int factor); + wxPoint operator /(const wxPoint& sz, int divisor); wxPoint operator *(const wxPoint& sz, int factor); wxPoint operator *(int factor, const wxPoint& sz); - wxPoint& operator /=(int factor); + wxPoint& operator /=(int divisor); wxPoint& operator *=(int factor); - wxPoint operator /(const wxPoint& pt, double factor); + wxPoint operator /(const wxPoint& pt, double divisor); ///@} From 8ccbd7e95df96f836f3b539250f78a27c5d244aa Mon Sep 17 00:00:00 2001 From: David Miguel Susano Pinto Date: Thu, 4 Jan 2024 01:16:48 +0000 Subject: [PATCH 200/257] Implement operator/=(int) and operator*=(int) for wxPoint and wxRealPoint. These operators are part of the documented interface but were never implemented. This commit implements them. --- include/wx/gdicmn.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 5467575e2c..6c8ac67ce4 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -469,6 +469,9 @@ public: wxRealPoint& operator+=(const wxSize& s) { x += s.GetWidth(); y += s.GetHeight(); return *this; } wxRealPoint& operator-=(const wxSize& s) { x -= s.GetWidth(); y -= s.GetHeight(); return *this; } + + wxRealPoint& operator/=(int i) { x *= i; y *= i; return *this; } + wxRealPoint& operator*=(int i) { x /= i; y /= i; return *this; } }; @@ -592,6 +595,9 @@ public: wxPoint& operator+=(const wxSize& s) { x += s.GetWidth(); y += s.GetHeight(); return *this; } wxPoint& operator-=(const wxSize& s) { x -= s.GetWidth(); y -= s.GetHeight(); return *this; } + wxPoint& operator/=(int i) { x /= i, y /= i; return *this; } + wxPoint& operator*=(int i) { x *= i, y *= i; return *this; } + // check if both components are set/initialized bool IsFullySpecified() const { return x != wxDefaultCoord && y != wxDefaultCoord; } From 66e7d0bce86f214ca8d880c68f311345c8cc46c2 Mon Sep 17 00:00:00 2001 From: David Miguel Susano Pinto Date: Thu, 4 Jan 2024 01:19:09 +0000 Subject: [PATCH 201/257] Implement + and - between wxRealPoint and wxSize. These operators are part of the documented interface for wxRealPoint but were never implemented. This commit implements them. --- include/wx/gdicmn.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 6c8ac67ce4..6f5d3b6ef8 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -490,12 +490,30 @@ inline wxRealPoint operator+(const wxRealPoint& p1, const wxRealPoint& p2) return wxRealPoint(p1.x + p2.x, p1.y + p2.y); } - inline wxRealPoint operator-(const wxRealPoint& p1, const wxRealPoint& p2) { return wxRealPoint(p1.x - p2.x, p1.y - p2.y); } +inline wxRealPoint operator+(const wxRealPoint& pt, const wxSize& sz) +{ + return wxRealPoint(pt.x + sz.GetWidth(), pt.y + sz.GetHeight()); +} + +inline wxRealPoint operator-(const wxRealPoint& pt, const wxSize& sz) +{ + return wxRealPoint(pt.x - sz.GetWidth(), pt.y - sz.GetHeight()); +} + +inline wxRealPoint operator+(const wxSize& sz, const wxRealPoint& pt) +{ + return wxRealPoint(sz.GetWidth() + pt.x, sz.GetHeight() + pt.y); +} + +inline wxRealPoint operator-(const wxSize& sz, const wxRealPoint& pt) +{ + return wxRealPoint(sz.GetWidth() - pt.x, sz.GetHeight() - pt.y); +} inline wxRealPoint operator/(const wxRealPoint& p, int i) { From 8638db50dae4d057765c9314bb1da27dcefc30f4 Mon Sep 17 00:00:00 2001 From: David Miguel Susano Pinto Date: Thu, 4 Jan 2024 01:21:47 +0000 Subject: [PATCH 202/257] Document a series of undocumented wxPoint and wxRealPoint operators. Unary minus of wxPoint and multiplication with double are implemented but undocumented. Many of operators that use integers types other than int remain undocumented though. --- interface/wx/gdicmn.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index 9305d54a31..f5bacacbce 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -233,6 +233,8 @@ public: wxRealPoint& operator /=(int divisor); wxRealPoint& operator *=(int factor); + wxRealPoint operator *(const wxRealPoint& pt, double factor); + wxRealPoint operator *(double factor, const wxRealPoint& pt); wxRealPoint operator /(const wxRealPoint& pt, double divisor); ///@} @@ -733,6 +735,8 @@ public: wxPoint& operator +=(const wxSize& sz); wxPoint& operator -=(const wxSize& sz); + wxPoint operator -(const wxPoint& pt); + wxPoint operator /(const wxPoint& sz, int divisor); wxPoint operator *(const wxPoint& sz, int factor); wxPoint operator *(int factor, const wxPoint& sz); @@ -740,6 +744,8 @@ public: wxPoint& operator *=(int factor); wxPoint operator /(const wxPoint& pt, double divisor); + wxPoint operator *(const wxPoint& pt, double factor); + wxPoint operator *(double factor, const wxPoint& pt); ///@} From b9b0cce41b61c8429b1ed75dc058be53462cc538 Mon Sep 17 00:00:00 2001 From: David Miguel Susano Pinto Date: Thu, 4 Jan 2024 01:25:12 +0000 Subject: [PATCH 203/257] include/wx/gdicmn.h: reorder to match the order in interface/wx/gdicmn.h. --- include/wx/gdicmn.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 6f5d3b6ef8..6ce7a2d8af 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -738,6 +738,11 @@ inline wxPoint operator*(unsigned long i, const wxPoint& p) return wxPoint(int(p.x * i), int(p.y * i)); } +inline wxPoint operator/(const wxPoint& p, double f) +{ + return wxPoint(wxRound(p.x / f), wxRound(p.y / f)); +} + inline wxPoint operator*(const wxPoint& p, double f) { return wxPoint(int(p.x * f), int(p.y * f)); @@ -748,11 +753,6 @@ inline wxPoint operator*(double f, const wxPoint& p) return wxPoint(int(p.x * f), int(p.y * f)); } -inline wxPoint operator/(const wxPoint& p, double f) -{ - return wxPoint(wxRound(p.x / f), wxRound(p.y / f)); -} - WX_DECLARE_LIST_WITH_DECL(wxPoint, wxPointList, class WXDLLIMPEXP_CORE); // --------------------------------------------------------------------------- From 11c3034177c64c33f65dc1833e37f00705e59ace Mon Sep 17 00:00:00 2001 From: David Miguel Susano Pinto Date: Thu, 4 Jan 2024 01:29:40 +0000 Subject: [PATCH 204/257] Implement unary minus for wxRealPoint, same as wxPoint. --- include/wx/gdicmn.h | 5 +++++ interface/wx/gdicmn.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 6ce7a2d8af..b67f34dbd7 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -515,6 +515,11 @@ inline wxRealPoint operator-(const wxSize& sz, const wxRealPoint& pt) return wxRealPoint(sz.GetWidth() - pt.x, sz.GetHeight() - pt.y); } +inline wxRealPoint operator-(const wxRealPoint& pt) +{ + return wxRealPoint(-pt.x, -pt.y); +} + inline wxRealPoint operator/(const wxRealPoint& p, int i) { return wxRealPoint(p.x / i, p.y / i); diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index f5bacacbce..83cbe5289f 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -227,6 +227,8 @@ public: wxRealPoint& operator +=(const wxSize& sz); wxRealPoint& operator -=(const wxSize& sz); + wxRealPoint operator -(const wxRealPoint& pt); + wxRealPoint operator /(const wxRealPoint& sz, int divisor); wxRealPoint operator *(const wxRealPoint& sz, int factor); wxRealPoint operator *(int factor, const wxRealPoint& pt); From 1300c56f0d823e484bbe52d20533895a708d7b6b Mon Sep 17 00:00:00 2001 From: David Miguel Susano Pinto Date: Thu, 4 Jan 2024 01:30:17 +0000 Subject: [PATCH 205/257] Put wxRealPoint operators in the same order as wxPoint ones --- include/wx/gdicmn.h | 10 +++++----- interface/wx/gdicmn.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index b67f34dbd7..d6615235d5 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -580,6 +580,11 @@ inline wxRealPoint operator*(unsigned long i, const wxRealPoint& p) return wxRealPoint(p.x * i, p.y * i); } +inline wxRealPoint operator/(const wxRealPoint& p, double f) +{ + return wxRealPoint(p.x / f, p.y / f); +} + inline wxRealPoint operator*(const wxRealPoint& p, double f) { return wxRealPoint(p.x * f, p.y * f); @@ -590,11 +595,6 @@ inline wxRealPoint operator*(double f, const wxRealPoint& p) return wxRealPoint(p.x * f, p.y * f); } -inline wxRealPoint operator/(const wxRealPoint& p, double f) -{ - return wxRealPoint(p.x / f, p.y / f); -} - // ---------------------------------------------------------------------------- // wxPoint: 2D point with integer coordinates diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index 83cbe5289f..09c29b2791 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -235,9 +235,9 @@ public: wxRealPoint& operator /=(int divisor); wxRealPoint& operator *=(int factor); + wxRealPoint operator /(const wxRealPoint& pt, double divisor); wxRealPoint operator *(const wxRealPoint& pt, double factor); wxRealPoint operator *(double factor, const wxRealPoint& pt); - wxRealPoint operator /(const wxRealPoint& pt, double divisor); ///@} /** From 68bef2fbf3d120305ba48438671d679f6238db2c Mon Sep 17 00:00:00 2001 From: David Miguel Susano Pinto Date: Thu, 4 Jan 2024 02:08:41 +0000 Subject: [PATCH 206/257] Add compound operators * and / to wxPoint and wxRealPoint Also add unit tests for them as well as for the existing additive compound operators. --- include/wx/gdicmn.h | 4 ++++ interface/wx/gdicmn.h | 4 ++++ tests/geometry/point.cpp | 44 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index d6615235d5..555ee6985a 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -472,6 +472,8 @@ public: wxRealPoint& operator/=(int i) { x *= i; y *= i; return *this; } wxRealPoint& operator*=(int i) { x /= i; y /= i; return *this; } + wxRealPoint& operator/=(double f) { x /= f; y /= f; return *this; } + wxRealPoint& operator*=(double f) { x *= f; y *= f; return *this; } }; @@ -620,6 +622,8 @@ public: wxPoint& operator/=(int i) { x /= i, y /= i; return *this; } wxPoint& operator*=(int i) { x *= i, y *= i; return *this; } + wxPoint& operator/=(double f) { x = wxRound(x/f); y = wxRound(y/f); return *this; } + wxPoint& operator*=(double f) { x = wxRound(x*f); y = wxRound(y*f); return *this; } // check if both components are set/initialized bool IsFullySpecified() const { return x != wxDefaultCoord && y != wxDefaultCoord; } diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index 09c29b2791..12105288c2 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -238,6 +238,8 @@ public: wxRealPoint operator /(const wxRealPoint& pt, double divisor); wxRealPoint operator *(const wxRealPoint& pt, double factor); wxRealPoint operator *(double factor, const wxRealPoint& pt); + wxRealPoint& operator /=(double divisor); + wxRealPoint& operator *=(double factor); ///@} /** @@ -748,6 +750,8 @@ public: wxPoint operator /(const wxPoint& pt, double divisor); wxPoint operator *(const wxPoint& pt, double factor); wxPoint operator *(double factor, const wxPoint& pt); + wxPoint& operator /=(double divisor); + wxPoint& operator *=(double factor); ///@} diff --git a/tests/geometry/point.cpp b/tests/geometry/point.cpp index aaf2867bd2..2f0dea08ff 100644 --- a/tests/geometry/point.cpp +++ b/tests/geometry/point.cpp @@ -51,6 +51,31 @@ TEST_CASE("wxPoint::Operators", "[point]") p6 = p2; p6 -= s; CHECK( p3 == p5 ); CHECK( p4 == p6 ); + + // Test arithmetic compound assignment operators with scalars + wxPoint p7(3, 5); + p7 /= 2; // chosen to check results truncate + CHECK( p7.x == 1 ); + CHECK( p7.y == 2 ); + p7 *= 2; + CHECK( p7.x == 2 ); + CHECK( p7.y == 4 ); + p7 *= 3.2; // chosen so that x and y rounds down and up respectively + CHECK( p7.x == 6 ); + CHECK( p7.y == 13 ); + p7 /= 1.1; // chosen so that x and y rounds up and down respectively + CHECK( p7.x == 5 ); + CHECK( p7.y == 12 ); + + // Test arithmetic compound assignment operators with wxSizes + wxSize s1(2, 3); + p7 += s1; + CHECK( p7.x == 7 ); + CHECK( p7.y == 15 ); + wxSize s2(3, 4); + p7 -= s2; + CHECK( p7.x == 4 ); + CHECK( p7.y == 11 ); } TEST_CASE("wxRealPoint::Operators", "[point]") @@ -66,4 +91,23 @@ TEST_CASE("wxRealPoint::Operators", "[point]") CHECK( p4.x == Approx(p6.x) ); CHECK( p4.y == Approx(p6.y) ); CHECK( p3.x != Approx(p4.x) ); + + // Test arithmetic compound assignment operators with scalars + wxRealPoint p7(3.0, 5.0); + p7 /= 2.0; + CHECK( p7.x == Approx(1.5) ); + CHECK( p7.y == Approx(2.5) ); + p7 *= 3.0; + CHECK( p7.x == Approx(4.5) ); + CHECK( p7.y == Approx(7.5) ); + + // Test arithmetic compound assignment operators with wxSizes + wxSize s1(2, 3); + p7 += s1; + CHECK( p7.x == Approx(6.5) ); + CHECK( p7.y == Approx(10.5) ); + wxSize s2(3, 4); + p7 -= s2; + CHECK( p7.x == Approx(3.5) ); + CHECK( p7.y == Approx(6.5) ); } From acb24e706692b6df035d9cc57da3cb079b3d7550 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 5 Jan 2024 01:02:08 +0100 Subject: [PATCH 207/257] Don't define operators on common GDI classes in global scope Use "hidden friend" idiom instead and define these operators as friend functions inside the corresponding class scope, so that they're only found using ADL and, in particular, don't appear as candidates when looking for any operator. In practice, this significantly reduces the error messages given if some operator (e.g. "==") is applied to a type not defined it, as the compiler doesn't need to consider converting this type to wxPoint, wxRealPoint, wxRect, wxSize etc, nor to complain about failing to do it. --- include/wx/gdicmn.h | 713 +++++++++++++++++++++--------------------- interface/wx/gdicmn.h | 113 +++---- 2 files changed, 406 insertions(+), 420 deletions(-) diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 555ee6985a..50d5043416 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -295,6 +295,102 @@ public: wxSize& operator/=(double i) { x = wxRound(x/i); y = wxRound(y/i); return *this; } wxSize& operator*=(double i) { x = wxRound(x*i); y = wxRound(y*i); return *this; } + friend bool operator==(const wxSize& s1, const wxSize& s2) + { + return s1.x == s2.x && s1.y == s2.y; + } + + friend bool operator!=(const wxSize& s1, const wxSize& s2) + { + return s1.x != s2.x || s1.y != s2.y; + } + + friend wxSize operator+(const wxSize& s1, const wxSize& s2) + { + return wxSize(s1.x + s2.x, s1.y + s2.y); + } + + friend wxSize operator-(const wxSize& s1, const wxSize& s2) + { + return wxSize(s1.x - s2.x, s1.y - s2.y); + } + + friend wxSize operator/(const wxSize& s, int i) + { + return wxSize(s.x / i, s.y / i); + } + + friend wxSize operator*(const wxSize& s, int i) + { + return wxSize(s.x * i, s.y * i); + } + + friend wxSize operator*(int i, const wxSize& s) + { + return wxSize(s.x * i, s.y * i); + } + + friend wxSize operator/(const wxSize& s, unsigned int i) + { + return wxSize(s.x / i, s.y / i); + } + + friend wxSize operator*(const wxSize& s, unsigned int i) + { + return wxSize(s.x * i, s.y * i); + } + + friend wxSize operator*(unsigned int i, const wxSize& s) + { + return wxSize(s.x * i, s.y * i); + } + + friend wxSize operator/(const wxSize& s, long i) + { + return wxSize(s.x / i, s.y / i); + } + + friend wxSize operator*(const wxSize& s, long i) + { + return wxSize(int(s.x * i), int(s.y * i)); + } + + friend wxSize operator*(long i, const wxSize& s) + { + return wxSize(int(s.x * i), int(s.y * i)); + } + + friend wxSize operator/(const wxSize& s, unsigned long i) + { + return wxSize(int(s.x / i), int(s.y / i)); + } + + friend wxSize operator*(const wxSize& s, unsigned long i) + { + return wxSize(int(s.x * i), int(s.y * i)); + } + + friend wxSize operator*(unsigned long i, const wxSize& s) + { + return wxSize(int(s.x * i), int(s.y * i)); + } + + friend wxSize operator/(const wxSize& s, double i) + { + return wxSize(wxRound(s.x / i), wxRound(s.y / i)); + } + + friend wxSize operator*(const wxSize& s, double i) + { + return wxSize(wxRound(s.x * i), wxRound(s.y * i)); + } + + friend wxSize operator*(double i, const wxSize& s) + { + return wxSize(wxRound(s.x * i), wxRound(s.y * i)); + } + + void IncTo(const wxSize& sz) { if ( sz.x > x ) x = sz.x; if ( sz.y > y ) y = sz.y; } void DecTo(const wxSize& sz) @@ -350,103 +446,6 @@ public: int GetY() const { return y; } }; -inline bool operator==(const wxSize& s1, const wxSize& s2) -{ - return s1.x == s2.x && s1.y == s2.y; -} - -inline bool operator!=(const wxSize& s1, const wxSize& s2) -{ - return s1.x != s2.x || s1.y != s2.y; -} - -inline wxSize operator+(const wxSize& s1, const wxSize& s2) -{ - return wxSize(s1.x + s2.x, s1.y + s2.y); -} - -inline wxSize operator-(const wxSize& s1, const wxSize& s2) -{ - return wxSize(s1.x - s2.x, s1.y - s2.y); -} - -inline wxSize operator/(const wxSize& s, int i) -{ - return wxSize(s.x / i, s.y / i); -} - -inline wxSize operator*(const wxSize& s, int i) -{ - return wxSize(s.x * i, s.y * i); -} - -inline wxSize operator*(int i, const wxSize& s) -{ - return wxSize(s.x * i, s.y * i); -} - -inline wxSize operator/(const wxSize& s, unsigned int i) -{ - return wxSize(s.x / i, s.y / i); -} - -inline wxSize operator*(const wxSize& s, unsigned int i) -{ - return wxSize(s.x * i, s.y * i); -} - -inline wxSize operator*(unsigned int i, const wxSize& s) -{ - return wxSize(s.x * i, s.y * i); -} - -inline wxSize operator/(const wxSize& s, long i) -{ - return wxSize(s.x / i, s.y / i); -} - -inline wxSize operator*(const wxSize& s, long i) -{ - return wxSize(int(s.x * i), int(s.y * i)); -} - -inline wxSize operator*(long i, const wxSize& s) -{ - return wxSize(int(s.x * i), int(s.y * i)); -} - -inline wxSize operator/(const wxSize& s, unsigned long i) -{ - return wxSize(int(s.x / i), int(s.y / i)); -} - -inline wxSize operator*(const wxSize& s, unsigned long i) -{ - return wxSize(int(s.x * i), int(s.y * i)); -} - -inline wxSize operator*(unsigned long i, const wxSize& s) -{ - return wxSize(int(s.x * i), int(s.y * i)); -} - -inline wxSize operator/(const wxSize& s, double i) -{ - return wxSize(wxRound(s.x / i), wxRound(s.y / i)); -} - -inline wxSize operator*(const wxSize& s, double i) -{ - return wxSize(wxRound(s.x * i), wxRound(s.y * i)); -} - -inline wxSize operator*(double i, const wxSize& s) -{ - return wxSize(wxRound(s.x * i), wxRound(s.y * i)); -} - - - // --------------------------------------------------------------------------- // Point classes: with real or integer coordinates // --------------------------------------------------------------------------- @@ -474,130 +473,129 @@ public: wxRealPoint& operator*=(int i) { x /= i; y /= i; return *this; } wxRealPoint& operator/=(double f) { x /= f; y /= f; return *this; } wxRealPoint& operator*=(double f) { x *= f; y *= f; return *this; } + + friend bool operator==(const wxRealPoint& p1, const wxRealPoint& p2) + { + return wxIsSameDouble(p1.x, p2.x) && wxIsSameDouble(p1.y, p2.y); + } + + friend bool operator!=(const wxRealPoint& p1, const wxRealPoint& p2) + { + return !(p1 == p2); + } + + friend wxRealPoint operator+(const wxRealPoint& p1, const wxRealPoint& p2) + { + return wxRealPoint(p1.x + p2.x, p1.y + p2.y); + } + + friend wxRealPoint operator-(const wxRealPoint& p1, const wxRealPoint& p2) + { + return wxRealPoint(p1.x - p2.x, p1.y - p2.y); + } + + friend wxRealPoint operator+(const wxRealPoint& pt, const wxSize& sz) + { + return wxRealPoint(pt.x + sz.GetWidth(), pt.y + sz.GetHeight()); + } + + friend wxRealPoint operator-(const wxRealPoint& pt, const wxSize& sz) + { + return wxRealPoint(pt.x - sz.GetWidth(), pt.y - sz.GetHeight()); + } + + friend wxRealPoint operator+(const wxSize& sz, const wxRealPoint& pt) + { + return wxRealPoint(sz.GetWidth() + pt.x, sz.GetHeight() + pt.y); + } + + friend wxRealPoint operator-(const wxSize& sz, const wxRealPoint& pt) + { + return wxRealPoint(sz.GetWidth() - pt.x, sz.GetHeight() - pt.y); + } + + friend wxRealPoint operator-(const wxRealPoint& pt) + { + return wxRealPoint(-pt.x, -pt.y); + } + + friend wxRealPoint operator/(const wxRealPoint& p, int i) + { + return wxRealPoint(p.x / i, p.y / i); + } + + friend wxRealPoint operator*(const wxRealPoint& p, int i) + { + return wxRealPoint(p.x * i, p.y * i); + } + + friend wxRealPoint operator*(int i, const wxRealPoint& p) + { + return wxRealPoint(p.x * i, p.y * i); + } + + friend wxRealPoint operator/(const wxRealPoint& p, unsigned int i) + { + return wxRealPoint(p.x / i, p.y / i); + } + + friend wxRealPoint operator*(const wxRealPoint& p, unsigned int i) + { + return wxRealPoint(p.x * i, p.y * i); + } + + friend wxRealPoint operator*(unsigned int i, const wxRealPoint& p) + { + return wxRealPoint(p.x * i, p.y * i); + } + + friend wxRealPoint operator/(const wxRealPoint& p, long i) + { + return wxRealPoint(p.x / i, p.y / i); + } + + friend wxRealPoint operator*(const wxRealPoint& p, long i) + { + return wxRealPoint(p.x * i, p.y * i); + } + + friend wxRealPoint operator*(long i, const wxRealPoint& p) + { + return wxRealPoint(p.x * i, p.y * i); + } + + friend wxRealPoint operator/(const wxRealPoint& p, unsigned long i) + { + return wxRealPoint(p.x / i, p.y / i); + } + + friend wxRealPoint operator*(const wxRealPoint& p, unsigned long i) + { + return wxRealPoint(p.x * i, p.y * i); + } + + friend wxRealPoint operator*(unsigned long i, const wxRealPoint& p) + { + return wxRealPoint(p.x * i, p.y * i); + } + + friend wxRealPoint operator/(const wxRealPoint& p, double f) + { + return wxRealPoint(p.x / f, p.y / f); + } + + friend wxRealPoint operator*(const wxRealPoint& p, double f) + { + return wxRealPoint(p.x * f, p.y * f); + } + + friend wxRealPoint operator*(double f, const wxRealPoint& p) + { + return wxRealPoint(p.x * f, p.y * f); + } }; -inline bool operator==(const wxRealPoint& p1, const wxRealPoint& p2) -{ - return wxIsSameDouble(p1.x, p2.x) && wxIsSameDouble(p1.y, p2.y); -} - -inline bool operator!=(const wxRealPoint& p1, const wxRealPoint& p2) -{ - return !(p1 == p2); -} - -inline wxRealPoint operator+(const wxRealPoint& p1, const wxRealPoint& p2) -{ - return wxRealPoint(p1.x + p2.x, p1.y + p2.y); -} - -inline wxRealPoint operator-(const wxRealPoint& p1, const wxRealPoint& p2) -{ - return wxRealPoint(p1.x - p2.x, p1.y - p2.y); -} - -inline wxRealPoint operator+(const wxRealPoint& pt, const wxSize& sz) -{ - return wxRealPoint(pt.x + sz.GetWidth(), pt.y + sz.GetHeight()); -} - -inline wxRealPoint operator-(const wxRealPoint& pt, const wxSize& sz) -{ - return wxRealPoint(pt.x - sz.GetWidth(), pt.y - sz.GetHeight()); -} - -inline wxRealPoint operator+(const wxSize& sz, const wxRealPoint& pt) -{ - return wxRealPoint(sz.GetWidth() + pt.x, sz.GetHeight() + pt.y); -} - -inline wxRealPoint operator-(const wxSize& sz, const wxRealPoint& pt) -{ - return wxRealPoint(sz.GetWidth() - pt.x, sz.GetHeight() - pt.y); -} - -inline wxRealPoint operator-(const wxRealPoint& pt) -{ - return wxRealPoint(-pt.x, -pt.y); -} - -inline wxRealPoint operator/(const wxRealPoint& p, int i) -{ - return wxRealPoint(p.x / i, p.y / i); -} - -inline wxRealPoint operator*(const wxRealPoint& p, int i) -{ - return wxRealPoint(p.x * i, p.y * i); -} - -inline wxRealPoint operator*(int i, const wxRealPoint& p) -{ - return wxRealPoint(p.x * i, p.y * i); -} - -inline wxRealPoint operator/(const wxRealPoint& p, unsigned int i) -{ - return wxRealPoint(p.x / i, p.y / i); -} - -inline wxRealPoint operator*(const wxRealPoint& p, unsigned int i) -{ - return wxRealPoint(p.x * i, p.y * i); -} - -inline wxRealPoint operator*(unsigned int i, const wxRealPoint& p) -{ - return wxRealPoint(p.x * i, p.y * i); -} - -inline wxRealPoint operator/(const wxRealPoint& p, long i) -{ - return wxRealPoint(p.x / i, p.y / i); -} - -inline wxRealPoint operator*(const wxRealPoint& p, long i) -{ - return wxRealPoint(p.x * i, p.y * i); -} - -inline wxRealPoint operator*(long i, const wxRealPoint& p) -{ - return wxRealPoint(p.x * i, p.y * i); -} - -inline wxRealPoint operator/(const wxRealPoint& p, unsigned long i) -{ - return wxRealPoint(p.x / i, p.y / i); -} - -inline wxRealPoint operator*(const wxRealPoint& p, unsigned long i) -{ - return wxRealPoint(p.x * i, p.y * i); -} - -inline wxRealPoint operator*(unsigned long i, const wxRealPoint& p) -{ - return wxRealPoint(p.x * i, p.y * i); -} - -inline wxRealPoint operator/(const wxRealPoint& p, double f) -{ - return wxRealPoint(p.x / f, p.y / f); -} - -inline wxRealPoint operator*(const wxRealPoint& p, double f) -{ - return wxRealPoint(p.x * f, p.y * f); -} - -inline wxRealPoint operator*(double f, const wxRealPoint& p) -{ - return wxRealPoint(p.x * f, p.y * f); -} - - // ---------------------------------------------------------------------------- // wxPoint: 2D point with integer coordinates // ---------------------------------------------------------------------------- @@ -625,6 +623,129 @@ public: wxPoint& operator/=(double f) { x = wxRound(x/f); y = wxRound(y/f); return *this; } wxPoint& operator*=(double f) { x = wxRound(x*f); y = wxRound(y*f); return *this; } + // comparison + friend bool operator==(const wxPoint& p1, const wxPoint& p2) + { + return p1.x == p2.x && p1.y == p2.y; + } + + friend bool operator!=(const wxPoint& p1, const wxPoint& p2) + { + return !(p1 == p2); + } + + + // arithmetic operations (component wise) + friend wxPoint operator+(const wxPoint& p1, const wxPoint& p2) + { + return wxPoint(p1.x + p2.x, p1.y + p2.y); + } + + friend wxPoint operator-(const wxPoint& p1, const wxPoint& p2) + { + return wxPoint(p1.x - p2.x, p1.y - p2.y); + } + + friend wxPoint operator+(const wxPoint& p, const wxSize& s) + { + return wxPoint(p.x + s.x, p.y + s.y); + } + + friend wxPoint operator-(const wxPoint& p, const wxSize& s) + { + return wxPoint(p.x - s.x, p.y - s.y); + } + + friend wxPoint operator+(const wxSize& s, const wxPoint& p) + { + return wxPoint(p.x + s.x, p.y + s.y); + } + + friend wxPoint operator-(const wxSize& s, const wxPoint& p) + { + return wxPoint(s.x - p.x, s.y - p.y); + } + + friend wxPoint operator-(const wxPoint& p) + { + return wxPoint(-p.x, -p.y); + } + + friend wxPoint operator/(const wxPoint& p, int i) + { + return wxPoint(p.x / i, p.y / i); + } + + friend wxPoint operator*(const wxPoint& p, int i) + { + return wxPoint(p.x * i, p.y * i); + } + + friend wxPoint operator*(int i, const wxPoint& p) + { + return wxPoint(p.x * i, p.y * i); + } + + friend wxPoint operator/(const wxPoint& p, unsigned int i) + { + return wxPoint(p.x / i, p.y / i); + } + + friend wxPoint operator*(const wxPoint& p, unsigned int i) + { + return wxPoint(p.x * i, p.y * i); + } + + friend wxPoint operator*(unsigned int i, const wxPoint& p) + { + return wxPoint(p.x * i, p.y * i); + } + + friend wxPoint operator/(const wxPoint& p, long i) + { + return wxPoint(p.x / i, p.y / i); + } + + friend wxPoint operator*(const wxPoint& p, long i) + { + return wxPoint(int(p.x * i), int(p.y * i)); + } + + friend wxPoint operator*(long i, const wxPoint& p) + { + return wxPoint(int(p.x * i), int(p.y * i)); + } + + friend wxPoint operator/(const wxPoint& p, unsigned long i) + { + return wxPoint(p.x / i, p.y / i); + } + + friend wxPoint operator*(const wxPoint& p, unsigned long i) + { + return wxPoint(int(p.x * i), int(p.y * i)); + } + + friend wxPoint operator*(unsigned long i, const wxPoint& p) + { + return wxPoint(int(p.x * i), int(p.y * i)); + } + + friend wxPoint operator/(const wxPoint& p, double f) + { + return wxPoint(wxRound(p.x / f), wxRound(p.y / f)); + } + + friend wxPoint operator*(const wxPoint& p, double f) + { + return wxPoint(int(p.x * f), int(p.y * f)); + } + + friend wxPoint operator*(double f, const wxPoint& p) + { + return wxPoint(int(p.x * f), int(p.y * f)); + } + // check if both components are set/initialized bool IsFullySpecified() const { return x != wxDefaultCoord && y != wxDefaultCoord; } @@ -639,129 +760,6 @@ public: }; -// comparison -inline bool operator==(const wxPoint& p1, const wxPoint& p2) -{ - return p1.x == p2.x && p1.y == p2.y; -} - -inline bool operator!=(const wxPoint& p1, const wxPoint& p2) -{ - return !(p1 == p2); -} - - -// arithmetic operations (component wise) -inline wxPoint operator+(const wxPoint& p1, const wxPoint& p2) -{ - return wxPoint(p1.x + p2.x, p1.y + p2.y); -} - -inline wxPoint operator-(const wxPoint& p1, const wxPoint& p2) -{ - return wxPoint(p1.x - p2.x, p1.y - p2.y); -} - -inline wxPoint operator+(const wxPoint& p, const wxSize& s) -{ - return wxPoint(p.x + s.x, p.y + s.y); -} - -inline wxPoint operator-(const wxPoint& p, const wxSize& s) -{ - return wxPoint(p.x - s.x, p.y - s.y); -} - -inline wxPoint operator+(const wxSize& s, const wxPoint& p) -{ - return wxPoint(p.x + s.x, p.y + s.y); -} - -inline wxPoint operator-(const wxSize& s, const wxPoint& p) -{ - return wxPoint(s.x - p.x, s.y - p.y); -} - -inline wxPoint operator-(const wxPoint& p) -{ - return wxPoint(-p.x, -p.y); -} - -inline wxPoint operator/(const wxPoint& p, int i) -{ - return wxPoint(p.x / i, p.y / i); -} - -inline wxPoint operator*(const wxPoint& p, int i) -{ - return wxPoint(p.x * i, p.y * i); -} - -inline wxPoint operator*(int i, const wxPoint& p) -{ - return wxPoint(p.x * i, p.y * i); -} - -inline wxPoint operator/(const wxPoint& p, unsigned int i) -{ - return wxPoint(p.x / i, p.y / i); -} - -inline wxPoint operator*(const wxPoint& p, unsigned int i) -{ - return wxPoint(p.x * i, p.y * i); -} - -inline wxPoint operator*(unsigned int i, const wxPoint& p) -{ - return wxPoint(p.x * i, p.y * i); -} - -inline wxPoint operator/(const wxPoint& p, long i) -{ - return wxPoint(p.x / i, p.y / i); -} - -inline wxPoint operator*(const wxPoint& p, long i) -{ - return wxPoint(int(p.x * i), int(p.y * i)); -} - -inline wxPoint operator*(long i, const wxPoint& p) -{ - return wxPoint(int(p.x * i), int(p.y * i)); -} - -inline wxPoint operator/(const wxPoint& p, unsigned long i) -{ - return wxPoint(p.x / i, p.y / i); -} - -inline wxPoint operator*(const wxPoint& p, unsigned long i) -{ - return wxPoint(int(p.x * i), int(p.y * i)); -} - -inline wxPoint operator*(unsigned long i, const wxPoint& p) -{ - return wxPoint(int(p.x * i), int(p.y * i)); -} - -inline wxPoint operator/(const wxPoint& p, double f) -{ - return wxPoint(wxRound(p.x / f), wxRound(p.y / f)); -} - -inline wxPoint operator*(const wxPoint& p, double f) -{ - return wxPoint(int(p.x * f), int(p.y * f)); -} - -inline wxPoint operator*(double f, const wxPoint& p) -{ - return wxPoint(int(p.x * f), int(p.y * f)); -} - WX_DECLARE_LIST_WITH_DECL(wxPoint, wxPointList, class WXDLLIMPEXP_CORE); // --------------------------------------------------------------------------- @@ -888,9 +886,24 @@ public: // like Union() but don't ignore empty rectangles wxRect& operator+=(const wxRect& rect); + friend WXDLLIMPEXP_CORE wxRect operator+(const wxRect& r1, const wxRect& r2); // intersections of two rectangles not testing for empty rectangles wxRect& operator*=(const wxRect& rect); + friend WXDLLIMPEXP_CORE wxRect operator*(const wxRect& r1, const wxRect& r2); + + // compare rectangles + friend bool operator==(const wxRect& r1, const wxRect& r2) + { + return (r1.x == r2.x) && (r1.y == r2.y) && + (r1.width == r2.width) && (r1.height == r2.height); + } + + friend bool operator!=(const wxRect& r1, const wxRect& r2) + { + return !(r1 == r2); + } + // centre this rectangle in the given (usually, but not necessarily, // larger) one @@ -920,24 +933,6 @@ public: }; -// compare rectangles -inline bool operator==(const wxRect& r1, const wxRect& r2) -{ - return (r1.x == r2.x) && (r1.y == r2.y) && - (r1.width == r2.width) && (r1.height == r2.height); -} - -inline bool operator!=(const wxRect& r1, const wxRect& r2) -{ - return !(r1 == r2); -} - -// like Union() but don't treat empty rectangles specially -WXDLLIMPEXP_CORE wxRect operator+(const wxRect& r1, const wxRect& r2); - -// intersections of two rectangles -WXDLLIMPEXP_CORE wxRect operator*(const wxRect& r1, const wxRect& r2); - // define functions which couldn't be defined above because of declarations // order inline void wxSize::IncBy(const wxPoint& pt) { IncBy(pt.x, pt.y); } diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index 12105288c2..bef77ab9d4 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -200,44 +200,41 @@ public: /** @name Miscellaneous operators - Note that these operators are documented as class members - (to make them easier to find) but, as their prototype shows, - they are implemented as global operators; note that this is - transparent to the user but it helps to understand why the - following functions are documented to take the wxPoint they - operate on as an explicit argument. + Note that binary operators are defined as friend functions inside this + class, making them accessible via argument-dependent lookup, but hidden + otherwise. */ ///@{ wxRealPoint& operator=(const wxRealPoint& pt); - bool operator ==(const wxRealPoint& p1, const wxRealPoint& p2); - bool operator !=(const wxRealPoint& p1, const wxRealPoint& p2); + friend bool operator ==(const wxRealPoint& p1, const wxRealPoint& p2); + friend bool operator !=(const wxRealPoint& p1, const wxRealPoint& p2); - wxRealPoint operator +(const wxRealPoint& p1, const wxRealPoint& p2); - wxRealPoint operator -(const wxRealPoint& p1, const wxRealPoint& p2); + friend wxRealPoint operator +(const wxRealPoint& p1, const wxRealPoint& p2); + friend wxRealPoint operator -(const wxRealPoint& p1, const wxRealPoint& p2); wxRealPoint& operator +=(const wxRealPoint& pt); wxRealPoint& operator -=(const wxRealPoint& pt); - wxRealPoint operator +(const wxRealPoint& pt, const wxSize& sz); - wxRealPoint operator -(const wxRealPoint& pt, const wxSize& sz); - wxRealPoint operator +(const wxSize& sz, const wxRealPoint& pt); - wxRealPoint operator -(const wxSize& sz, const wxRealPoint& pt); + friend wxRealPoint operator +(const wxRealPoint& pt, const wxSize& sz); + friend wxRealPoint operator -(const wxRealPoint& pt, const wxSize& sz); + friend wxRealPoint operator +(const wxSize& sz, const wxRealPoint& pt); + friend wxRealPoint operator -(const wxSize& sz, const wxRealPoint& pt); wxRealPoint& operator +=(const wxSize& sz); wxRealPoint& operator -=(const wxSize& sz); - wxRealPoint operator -(const wxRealPoint& pt); + friend wxRealPoint operator -(const wxRealPoint& pt); - wxRealPoint operator /(const wxRealPoint& sz, int divisor); - wxRealPoint operator *(const wxRealPoint& sz, int factor); - wxRealPoint operator *(int factor, const wxRealPoint& pt); + friend wxRealPoint operator /(const wxRealPoint& sz, int divisor); + friend wxRealPoint operator *(const wxRealPoint& sz, int factor); + friend wxRealPoint operator *(int factor, const wxRealPoint& pt); wxRealPoint& operator /=(int divisor); wxRealPoint& operator *=(int factor); - wxRealPoint operator /(const wxRealPoint& pt, double divisor); - wxRealPoint operator *(const wxRealPoint& pt, double factor); - wxRealPoint operator *(double factor, const wxRealPoint& pt); + friend wxRealPoint operator /(const wxRealPoint& pt, double divisor); + friend wxRealPoint operator *(const wxRealPoint& pt, double factor); + friend wxRealPoint operator *(double factor, const wxRealPoint& pt); wxRealPoint& operator /=(double divisor); wxRealPoint& operator *=(double factor); ///@} @@ -608,13 +605,13 @@ public: /** Inequality operator. */ - bool operator !=(const wxRect& r1, const wxRect& r2); + friend bool operator !=(const wxRect& r1, const wxRect& r2); ///@{ /** Like Union(), but doesn't treat empty rectangles specially. */ - wxRect operator +(const wxRect& r1, const wxRect& r2); + friend wxRect operator +(const wxRect& r1, const wxRect& r2); wxRect& operator +=(const wxRect& r); ///@} @@ -622,7 +619,7 @@ public: /** Returns the intersection of two rectangles (which may be empty). */ - wxRect operator *(const wxRect& r1, const wxRect& r2); + friend wxRect operator *(const wxRect& r1, const wxRect& r2); wxRect& operator *=(const wxRect& r); ///@} @@ -634,7 +631,7 @@ public: /** Equality operator. */ - bool operator ==(const wxRect& r1, const wxRect& r2); + friend bool operator ==(const wxRect& r1, const wxRect& r2); /** Height member. @@ -712,44 +709,41 @@ public: /** @name Miscellaneous operators - Note that these operators are documented as class members - (to make them easier to find) but, as their prototype shows, - they are implemented as global operators; note that this is - transparent to the user but it helps to understand why the - following functions are documented to take the wxPoint they - operate on as an explicit argument. + Note that binary operators are defined as friend functions inside this + class, making them accessible via argument-dependent lookup, but hidden + otherwise. */ ///@{ wxPoint& operator=(const wxPoint& pt); - bool operator ==(const wxPoint& p1, const wxPoint& p2); - bool operator !=(const wxPoint& p1, const wxPoint& p2); + friend bool operator ==(const wxPoint& p1, const wxPoint& p2); + friend bool operator !=(const wxPoint& p1, const wxPoint& p2); - wxPoint operator +(const wxPoint& p1, const wxPoint& p2); - wxPoint operator -(const wxPoint& p1, const wxPoint& p2); + friend wxPoint operator +(const wxPoint& p1, const wxPoint& p2); + friend wxPoint operator -(const wxPoint& p1, const wxPoint& p2); wxPoint& operator +=(const wxPoint& pt); wxPoint& operator -=(const wxPoint& pt); - wxPoint operator +(const wxPoint& pt, const wxSize& sz); - wxPoint operator -(const wxPoint& pt, const wxSize& sz); - wxPoint operator +(const wxSize& sz, const wxPoint& pt); - wxPoint operator -(const wxSize& sz, const wxPoint& pt); + friend wxPoint operator +(const wxPoint& pt, const wxSize& sz); + friend wxPoint operator -(const wxPoint& pt, const wxSize& sz); + friend wxPoint operator +(const wxSize& sz, const wxPoint& pt); + friend wxPoint operator -(const wxSize& sz, const wxPoint& pt); wxPoint& operator +=(const wxSize& sz); wxPoint& operator -=(const wxSize& sz); wxPoint operator -(const wxPoint& pt); - wxPoint operator /(const wxPoint& sz, int divisor); - wxPoint operator *(const wxPoint& sz, int factor); - wxPoint operator *(int factor, const wxPoint& sz); + friend wxPoint operator /(const wxPoint& sz, int divisor); + friend wxPoint operator *(const wxPoint& sz, int factor); + friend wxPoint operator *(int factor, const wxPoint& sz); wxPoint& operator /=(int divisor); wxPoint& operator *=(int factor); - wxPoint operator /(const wxPoint& pt, double divisor); - wxPoint operator *(const wxPoint& pt, double factor); - wxPoint operator *(double factor, const wxPoint& pt); + friend wxPoint operator /(const wxPoint& pt, double divisor); + friend wxPoint operator *(const wxPoint& pt, double factor); + friend wxPoint operator *(double factor, const wxPoint& pt); wxPoint& operator /=(double divisor); wxPoint& operator *=(double factor); ///@} @@ -1117,12 +1111,9 @@ public: Sizes can be added to or subtracted from each other or divided or multiplied by a number. - Note that these operators are documented as class members - (to make them easier to find) but, as their prototype shows, - they are implemented as global operators; note that this is - transparent to the user but it helps to understand why the - following functions are documented to take the wxSize they - operate on as an explicit argument. + Note that binary operators are defined as friend functions inside this + class, making them accessible via argument-dependent lookup, but hidden + otherwise. Also note that using @c double factor may result in rounding errors, as wxSize always stores @c int coordinates and the result is always @@ -1131,20 +1122,20 @@ public: ///@{ wxSize& operator=(const wxSize& sz); - bool operator ==(const wxSize& s1, const wxSize& s2); - bool operator !=(const wxSize& s1, const wxSize& s2); + friend bool operator ==(const wxSize& s1, const wxSize& s2); + friend bool operator !=(const wxSize& s1, const wxSize& s2); - wxSize operator +(const wxSize& s1, const wxSize& s2); - wxSize operator -(const wxSize& s1, const wxSize& s2); + friend wxSize operator +(const wxSize& s1, const wxSize& s2); + friend wxSize operator -(const wxSize& s1, const wxSize& s2); wxSize& operator +=(const wxSize& sz); wxSize& operator -=(const wxSize& sz); - wxSize operator /(const wxSize& sz, int factor); - wxSize operator /(const wxSize& sz, double factor); - wxSize operator *(const wxSize& sz, int factor); - wxSize operator *(const wxSize& sz, double factor); - wxSize operator *(int factor, const wxSize& sz); - wxSize operator *(double factor, const wxSize& sz); + friend wxSize operator /(const wxSize& sz, int factor); + friend wxSize operator /(const wxSize& sz, double factor); + friend wxSize operator *(const wxSize& sz, int factor); + friend wxSize operator *(const wxSize& sz, double factor); + friend wxSize operator *(int factor, const wxSize& sz); + friend wxSize operator *(double factor, const wxSize& sz); wxSize& operator /=(int factor); wxSize& operator /=(double factor); wxSize& operator *=(int factor); From 09515ad4ce26d69f7f6f74f8e2477d86faff2cfe Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 01:32:09 +0100 Subject: [PATCH 208/257] Make wxString and wxUniChar comparison operators friends too Don't define them in the global scope to improve error messages. Also move the rest of wxString operators into the class scope. --- include/wx/defs.h | 12 +- include/wx/string.h | 287 ++++++++++++++++++++---------------------- include/wx/unichar.h | 31 +++-- interface/wx/string.h | 100 +++++++-------- 4 files changed, 208 insertions(+), 222 deletions(-) diff --git a/include/wx/defs.h b/include/wx/defs.h index 707ad778a8..5359e120fc 100644 --- a/include/wx/defs.h +++ b/include/wx/defs.h @@ -782,19 +782,22 @@ typedef short int WXTYPE; #define wxDEFINE_COMPARISON(op, T1, T2, cmp) \ - inline bool operator op(T1 x, T2 y) { return cmp(x, y, op); } + friend bool operator op(T1 x, T2 y) { return cmp(x, y, op); } #define wxDEFINE_COMPARISON_REV(op, T1, T2, cmp, oprev) \ - inline bool operator op(T2 y, T1 x) { return cmp(x, y, oprev); } + friend bool operator op(T2 y, T1 x) { return cmp(x, y, oprev); } #define wxDEFINE_COMPARISON_BY_REV(op, T1, T2, oprev) \ - inline bool operator op(T1 x, T2 y) { return y oprev x; } + friend bool operator op(T1 x, T2 y) { return y oprev x; } /* Define all 6 comparison operators (==, !=, <, <=, >, >=) for the given types in the specified order. The implementation is provided by the cmp macro. Normally wxDEFINE_ALL_COMPARISONS should be used as comparison operators are usually symmetric. + + Note that comparison operators are defined as hidden friends and so this + macro can only be used inside the class declaration. */ #define wxDEFINE_COMPARISONS(T1, T2, cmp) \ wxFOR_ALL_COMPARISONS_3(wxDEFINE_COMPARISON, T1, T2, cmp) @@ -803,6 +806,9 @@ typedef short int WXTYPE; Define all 6 comparison operators (==, !=, <, <=, >, >=) for the given types in the specified order, implemented in terms of existing operators for the reverse order. + + Note that comparison operators are defined as hidden friends and so this + macro can only be used inside the class declaration. */ #define wxDEFINE_COMPARISONS_BY_REV(T1, T2) \ wxFOR_ALL_COMPARISONS_2_REV(wxDEFINE_COMPARISON_BY_REV, T1, T2) diff --git a/include/wx/string.h b/include/wx/string.h index aed2ca6e5e..32b99c4ec2 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -261,6 +261,36 @@ public: // "*(c_str() + 2)" work inline wxUniChar operator*() const; + // we also need to provide the operators for comparison with wxCStrData to + // resolve ambiguity between operator(const wxChar *,const wxString &) and + // operator(const wxChar *, const wxChar *) for "p == s.c_str()" + // + // notice that these are (shallow) pointer comparisons, not (deep) string ones +#define wxCMP_CHAR_CSTRDATA(p, s, op) p op s.AsChar() +#define wxCMP_WCHAR_CSTRDATA(p, s, op) p op s.AsWChar() + + wxDEFINE_ALL_COMPARISONS(const wchar_t *, const wxCStrData&, wxCMP_WCHAR_CSTRDATA) +#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING + wxDEFINE_ALL_COMPARISONS(const char *, const wxCStrData&, wxCMP_CHAR_CSTRDATA) +#endif // wxNO_IMPLICIT_WXSTRING_ENCODING + +#undef wxCMP_CHAR_CSTRDATA +#undef wxCMP_WCHAR_CSTRDATA + +#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING + // we need to define those to allow "size_t pos = p - s.c_str()" where p is + // some pointer into the string + friend size_t operator-(const char *p, const wxCStrData& cs) + { + return p - cs.AsChar(); + } +#endif // wxNO_IMPLICIT_WXSTRING_ENCODING + + friend size_t operator-(const wchar_t *p, const wxCStrData& cs) + { + return p - cs.AsWChar(); + } + private: // the wxString this object was returned for const wxString *m_str; @@ -2019,6 +2049,33 @@ public: friend wxString WXDLLIMPEXP_BASE operator+(const wchar_t *pwz, const wxString& string); + friend wxString operator+(const wxString& string, wxUniCharRef ch) + { return string + (wxUniChar)ch; } + friend wxString operator+(const wxString& string, char ch) + { return string + wxUniChar(ch); } + friend wxString operator+(const wxString& string, wchar_t ch) + { return string + wxUniChar(ch); } + friend wxString operator+(wxUniCharRef ch, const wxString& string) + { return (wxUniChar)ch + string; } + friend wxString operator+(char ch, const wxString& string) + { return wxUniChar(ch) + string; } + friend wxString operator+(wchar_t ch, const wxString& string) + { return wxUniChar(ch) + string; } + + + friend wxString operator+(const wxString& string, const wxScopedWCharBuffer& buf) + { return string + (const wchar_t *)buf; } + friend wxString operator+(const wxScopedWCharBuffer& buf, const wxString& string) + { return (const wchar_t *)buf + string; } + +#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING + friend wxString operator+(const wxString& string, const wxScopedCharBuffer& buf) + { return string + (const char *)buf; } + friend wxString operator+(const wxScopedCharBuffer& buf, const wxString& string) + { return (const char *)buf + string; } +#endif // wxNO_IMPLICIT_WXSTRING_ENCODING + + // stream-like functions // insert an int into string wxString& operator<<(int i) @@ -2114,6 +2171,83 @@ public: bool IsSameAs(int c, bool compareWithCase = true) const { return IsSameAs(wxUniChar(c), compareWithCase); } + // comparison operators: these are always case sensitive + + // With C strings (narrow and wide): + + #define wxCMP_WXCHAR_STRING(p, s, op) 0 op s.Cmp(p) + + wxDEFINE_ALL_COMPARISONS(const wchar_t *, const wxString&, wxCMP_WXCHAR_STRING) +#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING + wxDEFINE_ALL_COMPARISONS(const char *, const wxString&, wxCMP_WXCHAR_STRING) +#endif // wxNO_IMPLICIT_WXSTRING_ENCODING + + #undef wxCMP_WXCHAR_STRING + + // With wxString itself and related types. + friend bool operator==(const wxString& s1, const wxString& s2) + { return s1.IsSameAs(s2); } + friend bool operator!=(const wxString& s1, const wxString& s2) + { return !s1.IsSameAs(s2); } + friend bool operator< (const wxString& s1, const wxString& s2) + { return s1.Cmp(s2) < 0; } + friend bool operator> (const wxString& s1, const wxString& s2) + { return s1.Cmp(s2) > 0; } + friend bool operator<=(const wxString& s1, const wxString& s2) + { return s1.Cmp(s2) <= 0; } + friend bool operator>=(const wxString& s1, const wxString& s2) + { return s1.Cmp(s2) >= 0; } + + friend bool operator==(const wxString& s1, const wxCStrData& s2) + { return s1 == s2.AsString(); } + friend bool operator==(const wxCStrData& s1, const wxString& s2) + { return s1.AsString() == s2; } + friend bool operator!=(const wxString& s1, const wxCStrData& s2) + { return s1 != s2.AsString(); } + friend bool operator!=(const wxCStrData& s1, const wxString& s2) + { return s1.AsString() != s2; } + + friend bool operator==(const wxString& s1, const wxScopedWCharBuffer& s2) + { return (s1.Cmp((const wchar_t *)s2) == 0); } + friend bool operator==(const wxScopedWCharBuffer& s1, const wxString& s2) + { return (s2.Cmp((const wchar_t *)s1) == 0); } + friend bool operator!=(const wxString& s1, const wxScopedWCharBuffer& s2) + { return (s1.Cmp((const wchar_t *)s2) != 0); } + friend bool operator!=(const wxScopedWCharBuffer& s1, const wxString& s2) + { return (s2.Cmp((const wchar_t *)s1) != 0); } + +#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING + friend bool operator==(const wxString& s1, const wxScopedCharBuffer& s2) + { return (s1.Cmp((const char *)s2) == 0); } + friend bool operator==(const wxScopedCharBuffer& s1, const wxString& s2) + { return (s2.Cmp((const char *)s1) == 0); } + friend bool operator!=(const wxString& s1, const wxScopedCharBuffer& s2) + { return (s1.Cmp((const char *)s2) != 0); } + friend bool operator!=(const wxScopedCharBuffer& s1, const wxString& s2) + { return (s2.Cmp((const char *)s1) != 0); } +#endif // wxNO_IMPLICIT_WXSTRING_ENCODING + + // comparison with char + friend bool operator==(const wxUniChar& c, const wxString& s) { return s.IsSameAs(c); } + friend bool operator==(const wxUniCharRef& c, const wxString& s) { return s.IsSameAs(c); } + friend bool operator==(char c, const wxString& s) { return s.IsSameAs(c); } + friend bool operator==(wchar_t c, const wxString& s) { return s.IsSameAs(c); } + friend bool operator==(int c, const wxString& s) { return s.IsSameAs(c); } + friend bool operator==(const wxString& s, const wxUniChar& c) { return s.IsSameAs(c); } + friend bool operator==(const wxString& s, const wxUniCharRef& c) { return s.IsSameAs(c); } + friend bool operator==(const wxString& s, char c) { return s.IsSameAs(c); } + friend bool operator==(const wxString& s, wchar_t c) { return s.IsSameAs(c); } + friend bool operator!=(const wxUniChar& c, const wxString& s) { return !s.IsSameAs(c); } + friend bool operator!=(const wxUniCharRef& c, const wxString& s) { return !s.IsSameAs(c); } + friend bool operator!=(char c, const wxString& s) { return !s.IsSameAs(c); } + friend bool operator!=(wchar_t c, const wxString& s) { return !s.IsSameAs(c); } + friend bool operator!=(int c, const wxString& s) { return !s.IsSameAs(c); } + friend bool operator!=(const wxString& s, const wxUniChar& c) { return !s.IsSameAs(c); } + friend bool operator!=(const wxString& s, const wxUniCharRef& c) { return !s.IsSameAs(c); } + friend bool operator!=(const wxString& s, char c) { return !s.IsSameAs(c); } + friend bool operator!=(const wxString& s, wchar_t c) { return !s.IsSameAs(c); } + + // simple sub-string extraction // return substring starting at nFirst of length nCount (or till the end // if nCount = default value) @@ -3637,37 +3771,6 @@ inline wxString::reverse_iterator operator+(ptrdiff_t n, wxString::reverse_itera inline wxString::const_reverse_iterator operator+(ptrdiff_t n, wxString::const_reverse_iterator i) { return i + n; } -// notice that even though for many compilers the friend declarations above are -// enough, from the point of view of C++ standard we must have the declarations -// here as friend ones are not injected in the enclosing namespace and without -// them the code fails to compile with conforming compilers such as xlC or g++4 -wxString WXDLLIMPEXP_BASE operator+(const wxString& string1, const wxString& string2); -#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING -wxString WXDLLIMPEXP_BASE operator+(const wxString& string, const char *psz); -#endif // wxNO_IMPLICIT_WXSTRING_ENCODING -wxString WXDLLIMPEXP_BASE operator+(const wxString& string, const wchar_t *pwz); -#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING -wxString WXDLLIMPEXP_BASE operator+(const char *psz, const wxString& string); -#endif // wxNO_IMPLICIT_WXSTRING_ENCODING -wxString WXDLLIMPEXP_BASE operator+(const wchar_t *pwz, const wxString& string); - -wxString WXDLLIMPEXP_BASE operator+(const wxString& string, wxUniChar ch); -wxString WXDLLIMPEXP_BASE operator+(wxUniChar ch, const wxString& string); - -inline wxString operator+(const wxString& string, wxUniCharRef ch) - { return string + (wxUniChar)ch; } -inline wxString operator+(const wxString& string, char ch) - { return string + wxUniChar(ch); } -inline wxString operator+(const wxString& string, wchar_t ch) - { return string + wxUniChar(ch); } -inline wxString operator+(wxUniCharRef ch, const wxString& string) - { return (wxUniChar)ch + string; } -inline wxString operator+(char ch, const wxString& string) - { return wxUniChar(ch) + string; } -inline wxString operator+(wchar_t ch, const wxString& string) - { return wxUniChar(ch) + string; } - - #define wxGetEmptyString() wxString() // ---------------------------------------------------------------------------- @@ -4005,95 +4108,9 @@ public: // --------------------------------------------------------------------------- -// wxString comparison functions: operator versions are always case sensitive +// wxString iterators comparisons // --------------------------------------------------------------------------- -// comparison with C-style narrow and wide strings. -#define wxCMP_WXCHAR_STRING(p, s, op) 0 op s.Cmp(p) - -wxDEFINE_ALL_COMPARISONS(const wchar_t *, const wxString&, wxCMP_WXCHAR_STRING) -#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING -wxDEFINE_ALL_COMPARISONS(const char *, const wxString&, wxCMP_WXCHAR_STRING) -#endif // wxNO_IMPLICIT_WXSTRING_ENCODING - -#undef wxCMP_WXCHAR_STRING - -inline bool operator==(const wxString& s1, const wxString& s2) - { return s1.IsSameAs(s2); } -inline bool operator!=(const wxString& s1, const wxString& s2) - { return !s1.IsSameAs(s2); } -inline bool operator< (const wxString& s1, const wxString& s2) - { return s1.Cmp(s2) < 0; } -inline bool operator> (const wxString& s1, const wxString& s2) - { return s1.Cmp(s2) > 0; } -inline bool operator<=(const wxString& s1, const wxString& s2) - { return s1.Cmp(s2) <= 0; } -inline bool operator>=(const wxString& s1, const wxString& s2) - { return s1.Cmp(s2) >= 0; } - -inline bool operator==(const wxString& s1, const wxCStrData& s2) - { return s1 == s2.AsString(); } -inline bool operator==(const wxCStrData& s1, const wxString& s2) - { return s1.AsString() == s2; } -inline bool operator!=(const wxString& s1, const wxCStrData& s2) - { return s1 != s2.AsString(); } -inline bool operator!=(const wxCStrData& s1, const wxString& s2) - { return s1.AsString() != s2; } - -inline bool operator==(const wxString& s1, const wxScopedWCharBuffer& s2) - { return (s1.Cmp((const wchar_t *)s2) == 0); } -inline bool operator==(const wxScopedWCharBuffer& s1, const wxString& s2) - { return (s2.Cmp((const wchar_t *)s1) == 0); } -inline bool operator!=(const wxString& s1, const wxScopedWCharBuffer& s2) - { return (s1.Cmp((const wchar_t *)s2) != 0); } -inline bool operator!=(const wxScopedWCharBuffer& s1, const wxString& s2) - { return (s2.Cmp((const wchar_t *)s1) != 0); } - -#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING -inline bool operator==(const wxString& s1, const wxScopedCharBuffer& s2) - { return (s1.Cmp((const char *)s2) == 0); } -inline bool operator==(const wxScopedCharBuffer& s1, const wxString& s2) - { return (s2.Cmp((const char *)s1) == 0); } -inline bool operator!=(const wxString& s1, const wxScopedCharBuffer& s2) - { return (s1.Cmp((const char *)s2) != 0); } -inline bool operator!=(const wxScopedCharBuffer& s1, const wxString& s2) - { return (s2.Cmp((const char *)s1) != 0); } -#endif // wxNO_IMPLICIT_WXSTRING_ENCODING - -inline wxString operator+(const wxString& string, const wxScopedWCharBuffer& buf) - { return string + (const wchar_t *)buf; } -inline wxString operator+(const wxScopedWCharBuffer& buf, const wxString& string) - { return (const wchar_t *)buf + string; } - -#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING -inline wxString operator+(const wxString& string, const wxScopedCharBuffer& buf) - { return string + (const char *)buf; } -inline wxString operator+(const wxScopedCharBuffer& buf, const wxString& string) - { return (const char *)buf + string; } -#endif // wxNO_IMPLICIT_WXSTRING_ENCODING - -// comparison with char -inline bool operator==(const wxUniChar& c, const wxString& s) { return s.IsSameAs(c); } -inline bool operator==(const wxUniCharRef& c, const wxString& s) { return s.IsSameAs(c); } -inline bool operator==(char c, const wxString& s) { return s.IsSameAs(c); } -inline bool operator==(wchar_t c, const wxString& s) { return s.IsSameAs(c); } -inline bool operator==(int c, const wxString& s) { return s.IsSameAs(c); } -inline bool operator==(const wxString& s, const wxUniChar& c) { return s.IsSameAs(c); } -inline bool operator==(const wxString& s, const wxUniCharRef& c) { return s.IsSameAs(c); } -inline bool operator==(const wxString& s, char c) { return s.IsSameAs(c); } -inline bool operator==(const wxString& s, wchar_t c) { return s.IsSameAs(c); } -inline bool operator!=(const wxUniChar& c, const wxString& s) { return !s.IsSameAs(c); } -inline bool operator!=(const wxUniCharRef& c, const wxString& s) { return !s.IsSameAs(c); } -inline bool operator!=(char c, const wxString& s) { return !s.IsSameAs(c); } -inline bool operator!=(wchar_t c, const wxString& s) { return !s.IsSameAs(c); } -inline bool operator!=(int c, const wxString& s) { return !s.IsSameAs(c); } -inline bool operator!=(const wxString& s, const wxUniChar& c) { return !s.IsSameAs(c); } -inline bool operator!=(const wxString& s, const wxUniCharRef& c) { return !s.IsSameAs(c); } -inline bool operator!=(const wxString& s, char c) { return !s.IsSameAs(c); } -inline bool operator!=(const wxString& s, wchar_t c) { return !s.IsSameAs(c); } - - -// wxString iterators comparisons inline bool wxString::const_iterator::operator==(const iterator& i) const { return *this == const_iterator(i); } inline bool wxString::const_iterator::operator!=(const iterator& i) const @@ -4120,22 +4137,6 @@ inline bool wxString::iterator::operator<=(const const_iterator& i) const inline bool wxString::iterator::operator>=(const const_iterator& i) const { return i <= *this; } -// we also need to provide the operators for comparison with wxCStrData to -// resolve ambiguity between operator(const wxChar *,const wxString &) and -// operator(const wxChar *, const wxChar *) for "p == s.c_str()" -// -// notice that these are (shallow) pointer comparisons, not (deep) string ones -#define wxCMP_CHAR_CSTRDATA(p, s, op) p op s.AsChar() -#define wxCMP_WCHAR_CSTRDATA(p, s, op) p op s.AsWChar() - -wxDEFINE_ALL_COMPARISONS(const wchar_t *, const wxCStrData&, wxCMP_WCHAR_CSTRDATA) -#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING -wxDEFINE_ALL_COMPARISONS(const char *, const wxCStrData&, wxCMP_CHAR_CSTRDATA) -#endif // wxNO_IMPLICIT_WXSTRING_ENCODING - -#undef wxCMP_CHAR_CSTRDATA -#undef wxCMP_WCHAR_CSTRDATA - // ---------------------------------------------------------------------------- // Implement hashing using C++11 std::hash<>. // ---------------------------------------------------------------------------- @@ -4264,24 +4265,6 @@ inline wxUniChar wxCStrData::operator[](size_t n) const return (*m_str)[m_offset + n]; } -// ---------------------------------------------------------------------------- -// more wxCStrData operators -// ---------------------------------------------------------------------------- - -#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING -// we need to define those to allow "size_t pos = p - s.c_str()" where p is -// some pointer into the string -inline size_t operator-(const char *p, const wxCStrData& cs) -{ - return p - cs.AsChar(); -} -#endif // wxNO_IMPLICIT_WXSTRING_ENCODING - -inline size_t operator-(const wchar_t *p, const wxCStrData& cs) -{ - return p - cs.AsWChar(); -} - // ---------------------------------------------------------------------------- // implementation of wx[W]CharBuffer inline methods using wxCStrData // ---------------------------------------------------------------------------- diff --git a/include/wx/unichar.h b/include/wx/unichar.h index 19a0c6d1fb..c02facd83f 100644 --- a/include/wx/unichar.h +++ b/include/wx/unichar.h @@ -162,6 +162,9 @@ public: #undef wxDEFINE_UNICHAR_OPERATOR #undef wxDEFINE_UNCHAR_CMP_WITH_INT + wxDEFINE_COMPARISONS_BY_REV(char, const wxUniChar&) + wxDEFINE_COMPARISONS_BY_REV(wchar_t, const wxUniChar&) + // this is needed for expressions like 'Z'-c int operator-(const wxUniChar& c) const { return m_value - c.m_value; } int operator-(char c) const { return m_value - From8bit(c); } @@ -290,12 +293,23 @@ public: #undef wxDEFINE_UNICHARREF_OPERATOR #undef wxDEFINE_UNICHARREF_CMP_WITH_INT + // Comparison operators for the case when wxUniChar(Ref) is the second + // operand implemented in terms of member comparison functions + wxDEFINE_COMPARISONS_BY_REV(char, const wxUniCharRef&) + wxDEFINE_COMPARISONS_BY_REV(wchar_t, const wxUniCharRef&) + + wxDEFINE_COMPARISONS_BY_REV(const wxUniChar&, const wxUniCharRef&) + // for expressions like c-'A': int operator-(const wxUniCharRef& c) const { return UniChar() - c.UniChar(); } int operator-(const wxUniChar& c) const { return UniChar() - c; } int operator-(char c) const { return UniChar() - c; } int operator-(unsigned char c) const { return UniChar() - c; } int operator-(wchar_t c) const { return UniChar() - c; } + friend int operator-(char c1, const wxUniCharRef& c2) { return -(c2 - c1); } + friend int operator-(const wxUniChar& c1, const wxUniCharRef& c2) { return -(c2 - c1); } + friend int operator-(wchar_t c1, const wxUniCharRef& c2) { return -(c2 - c1); } + private: #if wxUSE_UNICODE_UTF8 @@ -365,21 +379,4 @@ void swap(wxUniCharRef&& lhs, wxUniCharRef&& rhs) rhs = tmp; } - -// Comparison operators for the case when wxUniChar(Ref) is the second operand -// implemented in terms of member comparison functions - -wxDEFINE_COMPARISONS_BY_REV(char, const wxUniChar&) -wxDEFINE_COMPARISONS_BY_REV(char, const wxUniCharRef&) - -wxDEFINE_COMPARISONS_BY_REV(wchar_t, const wxUniChar&) -wxDEFINE_COMPARISONS_BY_REV(wchar_t, const wxUniCharRef&) - -wxDEFINE_COMPARISONS_BY_REV(const wxUniChar&, const wxUniCharRef&) - -// for expressions like c-'A': -inline int operator-(char c1, const wxUniCharRef& c2) { return -(c2 - c1); } -inline int operator-(const wxUniChar& c1, const wxUniCharRef& c2) { return -(c2 - c1); } -inline int operator-(wchar_t c1, const wxUniCharRef& c2) { return -(c2 - c1); } - #endif /* _WX_UNICHAR_H_ */ diff --git a/interface/wx/string.h b/interface/wx/string.h index 7608c49658..451ba0b052 100644 --- a/interface/wx/string.h +++ b/interface/wx/string.h @@ -911,12 +911,12 @@ public: /** Concatenation: returns a new string equal to the concatenation of the operands. */ - wxString operator +(const wxString& x, const wxString& y); + friend wxString operator +(const wxString& x, const wxString& y); /** @overload */ - wxString operator +(const wxString& x, wxUniChar y); + friend wxString operator +(const wxString& x, wxUniChar y); wxString& operator<<(const wxString& s); wxString& operator<<(const char* psz); @@ -1015,6 +1015,54 @@ public: */ bool IsSameAs(wxUniChar ch, bool caseSensitive = true) const; + ///@{ + /** + Comparison operator for string types. + */ + friend bool operator==(const wxString& s1, const wxString& s2); + friend bool operator!=(const wxString& s1, const wxString& s2); + friend bool operator< (const wxString& s1, const wxString& s2); + friend bool operator> (const wxString& s1, const wxString& s2); + friend bool operator<=(const wxString& s1, const wxString& s2); + friend bool operator>=(const wxString& s1, const wxString& s2); + friend bool operator==(const wxString& s1, const wxCStrData& s2); + friend bool operator==(const wxCStrData& s1, const wxString& s2); + friend bool operator!=(const wxString& s1, const wxCStrData& s2); + friend bool operator!=(const wxCStrData& s1, const wxString& s2); + friend bool operator==(const wxString& s1, const wxWCharBuffer& s2); + friend bool operator==(const wxWCharBuffer& s1, const wxString& s2); + friend bool operator!=(const wxString& s1, const wxWCharBuffer& s2); + friend bool operator!=(const wxWCharBuffer& s1, const wxString& s2); + friend bool operator==(const wxString& s1, const wxCharBuffer& s2); + friend bool operator==(const wxCharBuffer& s1, const wxString& s2); + friend bool operator!=(const wxString& s1, const wxCharBuffer& s2); + friend bool operator!=(const wxCharBuffer& s1, const wxString& s2); + ///@} + + ///@{ + /** + Comparison operators char types. + */ + friend bool operator==(const wxUniChar& c, const wxString& s); + friend bool operator==(const wxUniCharRef& c, const wxString& s); + friend bool operator==(char c, const wxString& s); + friend bool operator==(wchar_t c, const wxString& s); + friend bool operator==(int c, const wxString& s); + friend bool operator==(const wxString& s, const wxUniChar& c); + friend bool operator==(const wxString& s, const wxUniCharRef& c); + friend bool operator==(const wxString& s, char c); + friend bool operator==(const wxString& s, wchar_t c); + friend bool operator!=(const wxUniChar& c, const wxString& s); + friend bool operator!=(const wxUniCharRef& c, const wxString& s); + friend bool operator!=(char c, const wxString& s); + friend bool operator!=(wchar_t c, const wxString& s); + friend bool operator!=(int c, const wxString& s); + friend bool operator!=(const wxString& s, const wxUniChar& c); + friend bool operator!=(const wxString& s, const wxUniCharRef& c); + friend bool operator!=(const wxString& s, char c); + friend bool operator!=(const wxString& s, wchar_t c); + ///@} + /** Returns @true if the string contents matches a mask containing '*' and '?'. */ @@ -1999,54 +2047,6 @@ public: -///@{ -/** - Comparison operator for string types. -*/ -inline bool operator==(const wxString& s1, const wxString& s2); -inline bool operator!=(const wxString& s1, const wxString& s2); -inline bool operator< (const wxString& s1, const wxString& s2); -inline bool operator> (const wxString& s1, const wxString& s2); -inline bool operator<=(const wxString& s1, const wxString& s2); -inline bool operator>=(const wxString& s1, const wxString& s2); -inline bool operator==(const wxString& s1, const wxCStrData& s2); -inline bool operator==(const wxCStrData& s1, const wxString& s2); -inline bool operator!=(const wxString& s1, const wxCStrData& s2); -inline bool operator!=(const wxCStrData& s1, const wxString& s2); -inline bool operator==(const wxString& s1, const wxWCharBuffer& s2); -inline bool operator==(const wxWCharBuffer& s1, const wxString& s2); -inline bool operator!=(const wxString& s1, const wxWCharBuffer& s2); -inline bool operator!=(const wxWCharBuffer& s1, const wxString& s2); -inline bool operator==(const wxString& s1, const wxCharBuffer& s2); -inline bool operator==(const wxCharBuffer& s1, const wxString& s2); -inline bool operator!=(const wxString& s1, const wxCharBuffer& s2); -inline bool operator!=(const wxCharBuffer& s1, const wxString& s2); -///@} - -///@{ -/** - Comparison operators char types. -*/ -inline bool operator==(const wxUniChar& c, const wxString& s); -inline bool operator==(const wxUniCharRef& c, const wxString& s); -inline bool operator==(char c, const wxString& s); -inline bool operator==(wchar_t c, const wxString& s); -inline bool operator==(int c, const wxString& s); -inline bool operator==(const wxString& s, const wxUniChar& c); -inline bool operator==(const wxString& s, const wxUniCharRef& c); -inline bool operator==(const wxString& s, char c); -inline bool operator==(const wxString& s, wchar_t c); -inline bool operator!=(const wxUniChar& c, const wxString& s); -inline bool operator!=(const wxUniCharRef& c, const wxString& s); -inline bool operator!=(char c, const wxString& s); -inline bool operator!=(wchar_t c, const wxString& s); -inline bool operator!=(int c, const wxString& s); -inline bool operator!=(const wxString& s, const wxUniChar& c); -inline bool operator!=(const wxString& s, const wxUniCharRef& c); -inline bool operator!=(const wxString& s, char c); -inline bool operator!=(const wxString& s, wchar_t c); -///@} - /** The global wxString instance of an empty string. Used extensively in the entire wxWidgets API. From 020f22de15b6f3b7e32be0359217f26df5ca6f75 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 01:43:15 +0100 Subject: [PATCH 209/257] Define comparison and arithmetic operators as hidden friends Change these operators in all the other classes to hidden friends too. --- include/wx/longlong.h | 87 ++++++++++++++++++++++------------- include/wx/sharedptr.h | 24 +++++----- include/wx/windowid.h | 102 ++++++++++++++++++++--------------------- 3 files changed, 118 insertions(+), 95 deletions(-) diff --git a/include/wx/longlong.h b/include/wx/longlong.h index ff735a8fcd..cad5c250ae 100644 --- a/include/wx/longlong.h +++ b/include/wx/longlong.h @@ -197,6 +197,8 @@ public: { return wxLongLongNative(m_ll + ll.m_ll); } wxLongLongNative& operator+=(const wxLongLongNative& ll) { m_ll += ll.m_ll; return *this; } + friend wxLongLongNative operator+(long l, const wxLongLongNative& ll) + { return ll + l; } wxLongLongNative operator+(const wxLongLong_t ll) const { return wxLongLongNative(m_ll + ll); } @@ -221,6 +223,10 @@ public: { return wxLongLongNative(m_ll - ll.m_ll); } wxLongLongNative& operator-=(const wxLongLongNative& ll) { m_ll -= ll.m_ll; return *this; } + friend wxLongLongNative operator-(long l, const wxLongLongNative& ll) + { + return wxLongLongNative(l) - ll; + } wxLongLongNative operator-(const wxLongLong_t ll) const { return wxLongLongNative(m_ll - ll); } @@ -314,6 +320,13 @@ public: bool operator>=(long l) const { return m_ll >= l; } + friend bool operator<(long l, const wxLongLongNative& ll) { return ll > l; } + friend bool operator>(long l, const wxLongLongNative& ll) { return ll < l; } + friend bool operator<=(long l, const wxLongLongNative& ll) { return ll >= l; } + friend bool operator>=(long l, const wxLongLongNative& ll) { return ll <= l; } + friend bool operator==(long l, const wxLongLongNative& ll) { return ll == l; } + friend bool operator!=(long l, const wxLongLongNative& ll) { return ll != l; } + // miscellaneous // return the string representation of this number @@ -421,6 +434,8 @@ public: { return wxULongLongNative(m_ll + ll.m_ll); } wxULongLongNative& operator+=(const wxULongLongNative& ll) { m_ll += ll.m_ll; return *this; } + friend wxULongLongNative operator+(unsigned long l, const wxULongLongNative& ull) + { return ull + l; } wxULongLongNative operator+(const wxULongLong_t ll) const { return wxULongLongNative(m_ll + ll); } @@ -440,6 +455,10 @@ public: { return wxULongLongNative(m_ll - ll.m_ll); } wxULongLongNative& operator-=(const wxULongLongNative& ll) { m_ll -= ll.m_ll; return *this; } + friend wxULongLongNative operator-(unsigned long l, const wxULongLongNative& ull) + { + return wxULongLongNative(l - ull.m_ll); + } wxULongLongNative operator-(const wxULongLong_t ll) const { return wxULongLongNative(m_ll - ll); } @@ -533,6 +552,13 @@ public: bool operator>=(unsigned long l) const { return m_ll >= l; } + friend bool operator<(unsigned long l, const wxULongLongNative& ull) { return ull > l; } + friend bool operator>(unsigned long l, const wxULongLongNative& ull) { return ull < l; } + friend bool operator<=(unsigned long l, const wxULongLongNative& ull) { return ull >= l; } + friend bool operator>=(unsigned long l, const wxULongLongNative& ull) { return ull <= l; } + friend bool operator==(unsigned long l, const wxULongLongNative& ull) { return ull == l; } + friend bool operator!=(unsigned long l, const wxULongLongNative& ull) { return ull != l; } + // miscellaneous // return the string representation of this number @@ -696,6 +722,8 @@ public: wxLongLongWx operator+(long l) const; wxLongLongWx& operator+=(long l); + friend wxLongLongWx operator+(long l, const wxLongLongWx& ll) { return ll + l; } + // pre increment operator wxLongLongWx& operator++(); @@ -709,6 +737,10 @@ public: // subtraction wxLongLongWx operator-(const wxLongLongWx& ll) const; wxLongLongWx& operator-=(const wxLongLongWx& ll); + friend wxLongLongWx operator-(long l, const wxLongLongWx& ll) + { + return wxLongLongWx(l) - ll; + } // pre decrement operator wxLongLongWx& operator--(); @@ -761,6 +793,13 @@ public: bool operator<=(long l) const { return *this < l || *this == l; } bool operator>=(long l) const { return *this > l || *this == l; } + friend bool operator<(long l, const wxLongLongWx& ll) { return ll > l; } + friend bool operator>(long l, const wxLongLongWx& ll) { return ll < l; } + friend bool operator<=(long l, const wxLongLongWx& ll) { return ll >= l; } + friend bool operator>=(long l, const wxLongLongWx& ll) { return ll <= l; } + friend bool operator==(long l, const wxLongLongWx& ll) { return ll == l; } + friend bool operator!=(long l, const wxLongLongWx& ll) { return ll != l; } + // multiplication wxLongLongWx operator*(const wxLongLongWx& ll) const; wxLongLongWx& operator*=(const wxLongLongWx& ll); @@ -920,6 +959,8 @@ public: wxULongLongWx& operator+=(const wxULongLongWx& ll); wxULongLongWx operator+(unsigned long l) const; wxULongLongWx& operator+=(unsigned long l); + friend wxULongLongWx operator+(unsigned long l, const wxULongLongWx& ull) + { return ull + l; } // pre increment operator wxULongLongWx& operator++(); @@ -931,6 +972,13 @@ public: wxLongLongWx operator-(const wxULongLongWx& ll) const; wxULongLongWx& operator-=(const wxULongLongWx& ll); + friend wxLongLongWx operator-(unsigned long l, const wxULongLongWx& ull) + { + const wxULongLongWx ret = wxULongLongWx(l) - ull; + return wxLongLongWx((wxInt32)ret.GetHi(),ret.GetLo()); + } + + // pre decrement operator wxULongLongWx& operator--(); @@ -977,6 +1025,13 @@ public: bool operator<=(unsigned long l) const { return *this < l || *this == l; } bool operator>=(unsigned long l) const { return *this > l || *this == l; } + friend bool operator<(unsigned long l, const wxULongLongWx& ull) { return ull > l; } + friend bool operator>(unsigned long l, const wxULongLongWx& ull) { return ull < l; } + friend bool operator<=(unsigned long l, const wxULongLongWx& ull) { return ull >= l; } + friend bool operator>=(unsigned long l, const wxULongLongWx& ull) { return ull <= l; } + friend bool operator==(unsigned long l, const wxULongLongWx& ull) { return ull == l; } + friend bool operator!=(unsigned long l, const wxULongLongWx& ull) { return ull != l; } + // multiplication wxULongLongWx operator*(const wxULongLongWx& ll) const; wxULongLongWx& operator*=(const wxULongLongWx& ll); @@ -1031,38 +1086,6 @@ private: #endif // wxUSE_LONGLONG_WX -// ---------------------------------------------------------------------------- -// binary operators -// ---------------------------------------------------------------------------- - -inline bool operator<(long l, const wxLongLong& ll) { return ll > l; } -inline bool operator>(long l, const wxLongLong& ll) { return ll < l; } -inline bool operator<=(long l, const wxLongLong& ll) { return ll >= l; } -inline bool operator>=(long l, const wxLongLong& ll) { return ll <= l; } -inline bool operator==(long l, const wxLongLong& ll) { return ll == l; } -inline bool operator!=(long l, const wxLongLong& ll) { return ll != l; } - -inline wxLongLong operator+(long l, const wxLongLong& ll) { return ll + l; } -inline wxLongLong operator-(long l, const wxLongLong& ll) -{ - return wxLongLong(l) - ll; -} - -inline bool operator<(unsigned long l, const wxULongLong& ull) { return ull > l; } -inline bool operator>(unsigned long l, const wxULongLong& ull) { return ull < l; } -inline bool operator<=(unsigned long l, const wxULongLong& ull) { return ull >= l; } -inline bool operator>=(unsigned long l, const wxULongLong& ull) { return ull <= l; } -inline bool operator==(unsigned long l, const wxULongLong& ull) { return ull == l; } -inline bool operator!=(unsigned long l, const wxULongLong& ull) { return ull != l; } - -inline wxULongLong operator+(unsigned long l, const wxULongLong& ull) { return ull + l; } - -inline wxLongLong operator-(unsigned long l, const wxULongLong& ull) -{ - const wxULongLong ret = wxULongLong(l) - ull; - return wxLongLong((wxInt32)ret.GetHi(),ret.GetLo()); -} - #if wxUSE_LONGLONG_NATIVE && wxUSE_STREAMS WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxULongLong_t value); diff --git a/include/wx/sharedptr.h b/include/wx/sharedptr.h index ba332ac2cf..1b88a77ee6 100644 --- a/include/wx/sharedptr.h +++ b/include/wx/sharedptr.h @@ -110,6 +110,18 @@ public: bool unique() const { return (m_ref ? m_ref->m_count == 1 : true); } long use_count() const { return (m_ref ? (long)m_ref->m_count : 0); } + template + friend bool operator == (wxSharedPtr const &a, wxSharedPtr const &b ) + { + return a.get() == b.get(); + } + + template + friend bool operator != (wxSharedPtr const &a, wxSharedPtr const &b ) + { + return a.get() != b.get(); + } + private: struct reftype @@ -154,16 +166,4 @@ private: } }; -template -bool operator == (wxSharedPtr const &a, wxSharedPtr const &b ) -{ - return a.get() == b.get(); -} - -template -bool operator != (wxSharedPtr const &a, wxSharedPtr const &b ) -{ - return a.get() != b.get(); -} - #endif // _WX_SHAREDPTR_H_ diff --git a/include/wx/windowid.h b/include/wx/windowid.h index a6618b6188..2d448169d6 100644 --- a/include/wx/windowid.h +++ b/include/wx/windowid.h @@ -74,6 +74,57 @@ public: return *this; } + // comparison operators + friend bool operator==(const wxWindowIDRef& lhs, const wxWindowIDRef& rhs) + { + return lhs.GetValue() == rhs.GetValue(); + } + + friend bool operator==(const wxWindowIDRef& lhs, int rhs) + { + return lhs.GetValue() == rhs; + } + + friend bool operator==(const wxWindowIDRef& lhs, long rhs) + { + return lhs.GetValue() == rhs; + } + + friend bool operator==(int lhs, const wxWindowIDRef& rhs) + { + return rhs == lhs; + } + + friend bool operator==(long lhs, const wxWindowIDRef& rhs) + { + return rhs == lhs; + } + + friend bool operator!=(const wxWindowIDRef& lhs, const wxWindowIDRef& rhs) + { + return !(lhs == rhs); + } + + friend bool operator!=(const wxWindowIDRef& lhs, int rhs) + { + return !(lhs == rhs); + } + + friend bool operator!=(const wxWindowIDRef& lhs, long rhs) + { + return !(lhs == rhs); + } + + friend bool operator!=(int lhs, const wxWindowIDRef& rhs) + { + return !(lhs == rhs); + } + + friend bool operator!=(long lhs, const wxWindowIDRef& rhs) + { + return !(lhs == rhs); + } + // access to the stored id value wxWindowID GetValue() const { @@ -114,57 +165,6 @@ private: wxWindowID m_id; }; -// comparison operators -inline bool operator==(const wxWindowIDRef& lhs, const wxWindowIDRef& rhs) -{ - return lhs.GetValue() == rhs.GetValue(); -} - -inline bool operator==(const wxWindowIDRef& lhs, int rhs) -{ - return lhs.GetValue() == rhs; -} - -inline bool operator==(const wxWindowIDRef& lhs, long rhs) -{ - return lhs.GetValue() == rhs; -} - -inline bool operator==(int lhs, const wxWindowIDRef& rhs) -{ - return rhs == lhs; -} - -inline bool operator==(long lhs, const wxWindowIDRef& rhs) -{ - return rhs == lhs; -} - -inline bool operator!=(const wxWindowIDRef& lhs, const wxWindowIDRef& rhs) -{ - return !(lhs == rhs); -} - -inline bool operator!=(const wxWindowIDRef& lhs, int rhs) -{ - return !(lhs == rhs); -} - -inline bool operator!=(const wxWindowIDRef& lhs, long rhs) -{ - return !(lhs == rhs); -} - -inline bool operator!=(int lhs, const wxWindowIDRef& rhs) -{ - return !(lhs == rhs); -} - -inline bool operator!=(long lhs, const wxWindowIDRef& rhs) -{ - return !(lhs == rhs); -} - // ---------------------------------------------------------------------------- // wxIdManager // ---------------------------------------------------------------------------- From bddd46d343d46f0a4848803befda48063f965bcd Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 01:46:04 +0100 Subject: [PATCH 210/257] Disable wxDeprecatedGUIConstants comparisons without 3.2 compat Start preparing for removing these deprecated comparison operators. --- include/wx/brush.h | 4 ++++ include/wx/font.h | 4 ++++ include/wx/pen.h | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/include/wx/brush.h b/include/wx/brush.h index 13cff58950..1d6b3416b7 100644 --- a/include/wx/brush.h +++ b/include/wx/brush.h @@ -102,6 +102,8 @@ extern WXDLLIMPEXP_DATA_CORE(wxBrushList*) wxTheBrushList; // to compile without warnings which it would otherwise provoke from some // compilers as it compares elements of different enums +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use wxBRUSHSTYLE_XXX constants only") inline bool operator==(wxBrushStyle s, wxDeprecatedGUIConstants t) { @@ -114,4 +116,6 @@ inline bool operator!=(wxBrushStyle s, wxDeprecatedGUIConstants t) return static_cast(s) != static_cast(t); } +#endif // WXWIN_COMPATIBILITY_3_2 + #endif // _WX_BRUSH_H_BASE_ diff --git a/include/wx/font.h b/include/wx/font.h index 0daab9c91e..b3aa02cd1e 100644 --- a/include/wx/font.h +++ b/include/wx/font.h @@ -671,6 +671,8 @@ extern WXDLLIMPEXP_DATA_CORE(wxFontList*) wxTheFontList; // to compile without warnings which it would otherwise provoke from some // compilers as it compares elements of different enums +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use wxFONTFAMILY_XXX constants") \ inline bool operator==(wxFontFamily s, wxDeprecatedGUIConstants t) { return static_cast(s) == static_cast(t); } @@ -690,4 +692,6 @@ wxDEPRECATED_MSG("use wxFONTWEIGHT_XXX constants") \ inline bool operator!=(wxFontWeight s, wxDeprecatedGUIConstants t) { return static_cast(s) != static_cast(t); } +#endif // WXWIN_COMPATIBILITY_3_2 + #endif // _WX_FONT_H_BASE_ diff --git a/include/wx/pen.h b/include/wx/pen.h index 6ae4df8f62..db76b9641d 100644 --- a/include/wx/pen.h +++ b/include/wx/pen.h @@ -133,6 +133,8 @@ extern WXDLLIMPEXP_DATA_CORE(wxPenList*) wxThePenList; // to compile without warnings which it would otherwise provoke from some // compilers as it compares elements of different enums +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use wxPENSTYLE_XXX constants") inline bool operator==(wxPenStyle s, wxDeprecatedGUIConstants t) { @@ -145,4 +147,6 @@ inline bool operator!=(wxPenStyle s, wxDeprecatedGUIConstants t) return static_cast(s) != static_cast(t); } +#endif // WXWIN_COMPATIBILITY_3_2 + #endif // _WX_PEN_H_BASE_ From 3b06ab65ff5b953c56ee8d5a438fed120c8aaa42 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 4 Jan 2024 03:30:00 +0100 Subject: [PATCH 211/257] Don't set CMAKE_CXX_STANDARD to 11 by default Use the compiler default C++ dialect if it is C++11 or higher and only explicitly request C++11 if the compiler can't compile a small test using C++11 features by default. This prevents from unnecessarily adding -std=c++11 to the compiler flags under Unix, even with compilers using e.g. C++17 by default. --- CMakeLists.txt | 3 --- build/cmake/init.cmake | 19 +++++++++++++++++++ build/cmake/options.cmake | 2 -- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 89cb1b1f9d..f6ae7f6210 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -97,9 +97,6 @@ endif() project(wxWidgets VERSION ${wxVERSION} LANGUAGES ${wxLANGUAGES}) -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - include(build/cmake/main.cmake) # Set the default startup project for Visual Studio diff --git a/build/cmake/init.cmake b/build/cmake/init.cmake index e229dcdd1c..f5dab11199 100644 --- a/build/cmake/init.cmake +++ b/build/cmake/init.cmake @@ -10,6 +10,25 @@ if(DEFINED wxBUILD_CXX_STANDARD AND NOT wxBUILD_CXX_STANDARD STREQUAL COMPILER_DEFAULT) set(CMAKE_CXX_STANDARD ${wxBUILD_CXX_STANDARD}) + set(CMAKE_CXX_STANDARD_REQUIRED ON) +else() + # If the standard is not set explicitly, check whether we can use C++11 + # without any special options. + include(CheckCXXSourceCompiles) + check_cxx_source_compiles(" + #include + int main() { + std::vector v{1,2,3}; + for (auto& n : v) + --n; + return v[0]; + }" + wxHAVE_CXX11) + if(NOT wxHAVE_CXX11) + # If not, request it explicitly and let CMake check if it's supported. + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) + endif() endif() if(MSVC) diff --git a/build/cmake/options.cmake b/build/cmake/options.cmake index 7887f1ef50..bde248f25c 100644 --- a/build/cmake/options.cmake +++ b/build/cmake/options.cmake @@ -46,8 +46,6 @@ endif() # support setting the C++ standard, present it an option to the user if(DEFINED CMAKE_CXX_STANDARD) set(wxCXX_STANDARD_DEFAULT ${CMAKE_CXX_STANDARD}) -elseif(APPLE) - set(wxCXX_STANDARD_DEFAULT 11) else() set(wxCXX_STANDARD_DEFAULT COMPILER_DEFAULT) endif() From 9d21630069689e329e4594e72400c5145c216430 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 15:25:01 +0100 Subject: [PATCH 212/257] Don't leak wxMSWHeaderCtrlCustomDraw in dark mode The pointer may have been already allocated when the code initializing it in Create() when using dark mode is executed, so unconditionally reassigning to it leaked memory. --- src/msw/headerctrl.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index 56e3eb2e40..f1ecaacf05 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -221,7 +221,11 @@ bool wxMSWHeaderCtrl::Create(wxWindow *parent, if ( wxMSWDarkMode::IsActive() ) { - m_customDraw = new wxMSWHeaderCtrlCustomDraw(); + // Note that it may have been already allocated by MSWCreateControl() + // which calls SetFont() from InheritAttributes(), so don't recreate it + // in this case. + if ( !m_customDraw ) + m_customDraw = new wxMSWHeaderCtrlCustomDraw(); m_customDraw->UseHeaderThemeColors(GetHwnd()); } From 069ffbeaff18674d1aeb8e42949d4f81451bcb8f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 15:27:55 +0100 Subject: [PATCH 213/257] Use std::unique_ptr and not raw pointer Make memory leaks, such as the one fixed by the previous commit, impossible by making a smart pointer instead of a raw one for this object. No real changes. --- src/msw/headerctrl.cpp | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index f1ecaacf05..6342285f03 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -38,6 +38,8 @@ #include "wx/msw/private/darkmode.h" #include "wx/msw/private/winstyle.h" +#include + #ifndef HDM_SETBITMAPMARGIN #define HDM_SETBITMAPMARGIN 0x1234 #endif @@ -177,7 +179,7 @@ private: // the custom draw helper: initially nullptr, created on demand, use // GetCustomDraw() to do it - wxMSWHeaderCtrlCustomDraw *m_customDraw; + std::unique_ptr m_customDraw; }; // ============================================================================ @@ -197,7 +199,6 @@ void wxMSWHeaderCtrl::Init() m_scrollOffset = 0; m_colBeingDragged = -1; m_isColBeingResized = false; - m_customDraw = nullptr; Bind(wxEVT_DPI_CHANGED, &wxMSWHeaderCtrl::WXHandleDPIChanged, this); } @@ -225,7 +226,7 @@ bool wxMSWHeaderCtrl::Create(wxWindow *parent, // which calls SetFont() from InheritAttributes(), so don't recreate it // in this case. if ( !m_customDraw ) - m_customDraw = new wxMSWHeaderCtrlCustomDraw(); + m_customDraw.reset(new wxMSWHeaderCtrlCustomDraw()); m_customDraw->UseHeaderThemeColors(GetHwnd()); } @@ -269,7 +270,6 @@ bool wxMSWHeaderCtrl::MSWGetDarkModeSupport(MSWDarkModeSupport& support) const wxMSWHeaderCtrl::~wxMSWHeaderCtrl() { delete m_imageList; - delete m_customDraw; } // ---------------------------------------------------------------------------- @@ -666,20 +666,16 @@ wxMSWHeaderCtrlCustomDraw* wxMSWHeaderCtrl::GetCustomDraw() // any longer. if ( !m_hasBgCol && !m_hasFgCol && !wxMSWDarkMode::IsActive() ) { - if ( m_customDraw ) - { - delete m_customDraw; - m_customDraw = nullptr; - } - - return nullptr; + m_customDraw.reset(); + } + else + { + // We do have at least one custom colour, so enable custom drawing. + if ( !m_customDraw ) + m_customDraw.reset(new wxMSWHeaderCtrlCustomDraw()); } - // We do have at least one custom colour, so enable custom drawing. - if ( !m_customDraw ) - m_customDraw = new wxMSWHeaderCtrlCustomDraw(); - - return m_customDraw; + return m_customDraw.get(); } bool wxMSWHeaderCtrl::SetBackgroundColour(const wxColour& colour) From c1754d403372d4dc67b0583091ecb3d167875811 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 15:29:59 +0100 Subject: [PATCH 214/257] Also use std::unique_ptr instead of raw pointer Similar to the previous commit and done for consistency and safety. --- src/msw/headerctrl.cpp | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index 6342285f03..feb4cfed83 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -71,8 +71,6 @@ public: long style, const wxString& name); - virtual ~wxMSWHeaderCtrl(); - // Override to implement colours support via custom drawing. virtual bool SetBackgroundColour(const wxColour& colour) override; virtual bool SetForegroundColour(const wxColour& colour) override; @@ -166,7 +164,7 @@ private: wxArrayInt m_colIndices; // the image list: initially nullptr, created on demand - wxImageList *m_imageList; + std::unique_ptr m_imageList; // the offset of the window used to emulate scrolling it int m_scrollOffset; @@ -195,7 +193,6 @@ extern WXDLLIMPEXP_DATA_CORE(const char) wxMSWHeaderCtrlNameStr[] = "wxMSWHeader void wxMSWHeaderCtrl::Init() { m_numColumns = 0; - m_imageList = nullptr; m_scrollOffset = 0; m_colBeingDragged = -1; m_isColBeingResized = false; @@ -267,11 +264,6 @@ bool wxMSWHeaderCtrl::MSWGetDarkModeSupport(MSWDarkModeSupport& support) const return true; } -wxMSWHeaderCtrl::~wxMSWHeaderCtrl() -{ - delete m_imageList; -} - // ---------------------------------------------------------------------------- // wxMSWHeaderCtrl scrolling // ---------------------------------------------------------------------------- @@ -329,8 +321,7 @@ void wxMSWHeaderCtrl::MSWUpdateFontOnDPIChange(const wxSize& newDPI) void wxMSWHeaderCtrl::WXHandleDPIChanged(wxDPIChangedEvent& event) { - delete m_imageList; - m_imageList = nullptr; + m_imageList.reset(); for (unsigned int i = 0; i < m_numColumns; ++i) { UpdateHeader(i); @@ -462,7 +453,7 @@ void wxMSWHeaderCtrl::DoInsertItem(const wxHeaderColumn& col, unsigned int idx) if ( !m_imageList ) { bmpSize = bb.GetPreferredBitmapSizeFor(this); - m_imageList = new wxImageList(bmpSize.x, bmpSize.y); + m_imageList.reset(new wxImageList(bmpSize.x, bmpSize.y)); (void) // suppress mingw32 warning about unused computed value Header_SetImageList(GetHwnd(), GetHimagelistOf(m_imageList)); } From 735fe67182363fdbad7422ae2f3f76e545c745c7 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 15:31:45 +0100 Subject: [PATCH 215/257] Initialize wxMSWHeaderCtrl members in their declarations No real changes, just prefer initializing members directly when declaring them instead of doing it in a separate Init() function. --- src/msw/headerctrl.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index feb4cfed83..862b8dcb4e 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -144,7 +144,7 @@ private: // the number of columns in the control, including the hidden ones (not // taken into account by the native control, see comment in DoGetCount()) - unsigned int m_numColumns; + unsigned int m_numColumns = 0; // this is a lookup table allowing us to check whether the column with the // given index is currently shown in the native control, in which case the @@ -167,13 +167,13 @@ private: std::unique_ptr m_imageList; // the offset of the window used to emulate scrolling it - int m_scrollOffset; + int m_scrollOffset = 0; // actual column we are dragging or -1 if not dragging anything - int m_colBeingDragged; + int m_colBeingDragged = -1; // a column is currently being resized - bool m_isColBeingResized; + bool m_isColBeingResized = false; // the custom draw helper: initially nullptr, created on demand, use // GetCustomDraw() to do it @@ -192,11 +192,6 @@ extern WXDLLIMPEXP_DATA_CORE(const char) wxMSWHeaderCtrlNameStr[] = "wxMSWHeader void wxMSWHeaderCtrl::Init() { - m_numColumns = 0; - m_scrollOffset = 0; - m_colBeingDragged = -1; - m_isColBeingResized = false; - Bind(wxEVT_DPI_CHANGED, &wxMSWHeaderCtrl::WXHandleDPIChanged, this); } From a3fc9283f751c4cb108988f8394fbec45c309927 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 15:33:22 +0100 Subject: [PATCH 216/257] Remove useless wxMSWHeaderCtrl::Init() This was supposed to be "common part of all ctors" but there is just a single ctor in this class and even this one doesn't really need to call Bind(), which was the only thing done in Init() since the last commit, as it can, and should be, called by Create() after successfully creating the window instead. No real changes, just a simplification. --- src/msw/headerctrl.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/msw/headerctrl.cpp b/src/msw/headerctrl.cpp index 862b8dcb4e..c152d7bb8e 100644 --- a/src/msw/headerctrl.cpp +++ b/src/msw/headerctrl.cpp @@ -61,7 +61,6 @@ public: explicit wxMSWHeaderCtrl(wxHeaderCtrl& header) : m_header(header) { - Init(); } bool Create(wxWindow *parent, @@ -104,9 +103,6 @@ private: virtual WXDWORD MSWGetStyle(long style, WXDWORD *exstyle) const override; virtual bool MSWOnNotify(int idCtrl, WXLPARAM lParam, WXLPARAM *result) override; - // common part of all ctors - void Init(); - // wrapper around Header_InsertItem(): insert the item using information // from the given column at the given index void DoInsertItem(const wxHeaderColumn& col, unsigned int idx); @@ -190,11 +186,6 @@ extern WXDLLIMPEXP_DATA_CORE(const char) wxMSWHeaderCtrlNameStr[] = "wxMSWHeader // wxMSWHeaderCtrl construction/destruction // ---------------------------------------------------------------------------- -void wxMSWHeaderCtrl::Init() -{ - Bind(wxEVT_DPI_CHANGED, &wxMSWHeaderCtrl::WXHandleDPIChanged, this); -} - bool wxMSWHeaderCtrl::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, @@ -212,6 +203,8 @@ bool wxMSWHeaderCtrl::Create(wxWindow *parent, if ( !MSWCreateControl(WC_HEADER, wxT(""), pos, size) ) return false; + Bind(wxEVT_DPI_CHANGED, &wxMSWHeaderCtrl::WXHandleDPIChanged, this); + if ( wxMSWDarkMode::IsActive() ) { // Note that it may have been already allocated by MSWCreateControl() From 97468661c750ead4ea54579b2b570a2132103708 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 17:36:29 +0100 Subject: [PATCH 217/257] Fix drawing right and bottom wxMSW wxStaticBox edges in high DPI Passing window size divided by "scale" to CreateWithDIPSize() was wrong as the resulting bitmap could be too small to cover the entire window due to rounding errors, e.g. at 200% DPI the right and bottom row/column was never drawn on if the window size in the corresponding direction was odd. This notably fixes their (dis)appearance in dark mode, where we always draw them ourselves (otherwise we mostly only do it when using non-default colour). --- src/msw/statbox.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/msw/statbox.cpp b/src/msw/statbox.cpp index c6f0b9f75e..6ef086b73d 100644 --- a/src/msw/statbox.cpp +++ b/src/msw/statbox.cpp @@ -718,8 +718,8 @@ void wxStaticBox::OnPaint(wxPaintEvent& WXUNUSED(event)) wxMemoryDC memdc(&dc); const double scale = dc.GetContentScaleFactor(); - wxBitmap bitmap; - bitmap.CreateWithDIPSize(rc.right / scale, rc.bottom / scale, scale); + wxBitmap bitmap(rc.right, rc.bottom); + bitmap.SetScaleFactor(scale); memdc.SelectObject(bitmap); PaintBackground(memdc, rc); From 4833c67f794c1a92e70285a11467a713395b8048 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 19:54:31 +0100 Subject: [PATCH 218/257] Document that wxBitmapBundle also provides wxVariant support Don't use IMPLEMENT_VARIANT_OBJECT() in the documentation, this is completely unnecessary. --- interface/wx/variant.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/interface/wx/variant.h b/interface/wx/variant.h index 7c2701da79..08c61c49f8 100644 --- a/interface/wx/variant.h +++ b/interface/wx/variant.h @@ -73,12 +73,11 @@ wxObject itself. By default, wxWidgets already implements the shift operator conversion for a few of its drawing related classes: - @code - IMPLEMENT_VARIANT_OBJECT(wxColour) - IMPLEMENT_VARIANT_OBJECT(wxImage) - IMPLEMENT_VARIANT_OBJECT(wxIcon) - IMPLEMENT_VARIANT_OBJECT(wxBitmap) - @endcode + - wxColour + - wxImage + - wxIcon + - wxBitmap + - wxBitmapBundle Note that as of wxWidgets 2.9.0, wxVariantData no longer inherits from wxObject and wxVariant no longer uses the type-unsafe wxList class for list From b681a80b961de812f96bb8567d93e01ea7366e83 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 17:23:06 +0100 Subject: [PATCH 219/257] Explicitly create all sub-controls in wxPropertyGridManager::Create() Instead of deferring creation of wxPropertyGrid and other controls to EVT_SIZE handler we can create them when wxPropertyGridManager is created and its initial size is known. This way we can avoid using a trick with magic number used as a flag to determine when to create all controls in OnResize(). Closes #24171. --- src/propgrid/manager.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/propgrid/manager.cpp b/src/propgrid/manager.cpp index e4e3d33de1..639b71991c 100644 --- a/src/propgrid/manager.cpp +++ b/src/propgrid/manager.cpp @@ -634,6 +634,8 @@ bool wxPropertyGridManager::Create( wxWindow *parent, Init2(style); SetInitialSize(size); + // Create controls + RecreateControls(); return res; } @@ -763,9 +765,6 @@ void wxPropertyGridManager::Init2( int style ) // (see wxPropertyGridManager::ProcessEvent). ReconnectEventHandlers(wxID_NONE, m_pPropGrid->GetId()); - // Optional initial controls. - m_width = -12345; - m_iFlags |= wxPG_MAN_FL_INITIALIZED; } @@ -2149,9 +2148,6 @@ void wxPropertyGridManager::OnResize( wxSizeEvent& WXUNUSED(event) ) GetClientSize(&width, &height); - if ( m_width == -12345 ) - RecreateControls(); - RecalculatePositions(width, height); if ( m_pPropGrid && m_pPropGrid->GetParent() ) From 031435bd3973192a2ba07097921e02a0dd45bea8 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 17:25:08 +0100 Subject: [PATCH 220/257] Use dedicated function to obtain decimal separator in propgrid sample --- samples/propgrid/sampleprops.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/propgrid/sampleprops.cpp b/samples/propgrid/sampleprops.cpp index a128ac87e3..986e4eafc2 100644 --- a/samples/propgrid/sampleprops.cpp +++ b/samples/propgrid/sampleprops.cpp @@ -490,7 +490,7 @@ wxArrayDoubleProperty::wxArrayDoubleProperty (const wxString& label, // (i.e. can't use comma when comma acts as decimal point in float). wxChar use_delimiter = ','; - if (wxString::Format("%.2f",12.34).Find(use_delimiter) >= 0) + if ( wxNumberFormatter::GetDecimalSeparator() == use_delimiter ) use_delimiter = ';'; m_delimiter = use_delimiter; From ca3acd7a03ac9dce4f4195b717288cd96aa3ab8f Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 17:26:12 +0100 Subject: [PATCH 221/257] Use enum class to implement wxPGPropValFormatFlags as bitmask This is for better type safety of the flags. --- include/wx/propgrid/advprops.h | 138 ++++++++-- include/wx/propgrid/property.h | 149 +++++++++-- include/wx/propgrid/propgrid.h | 11 +- include/wx/propgrid/propgriddefs.h | 77 +++++- include/wx/propgrid/propgridiface.h | 14 +- include/wx/propgrid/props.h | 370 +++++++++++++++++++++----- interface/wx/propgrid/advprops.h | 47 ++-- interface/wx/propgrid/property.h | 81 +++--- interface/wx/propgrid/propgrid.h | 4 +- interface/wx/propgrid/propgriddefs.h | 25 +- interface/wx/propgrid/propgridiface.h | 4 +- interface/wx/propgrid/props.h | 125 ++++----- samples/propgrid/sampleprops.cpp | 10 +- samples/propgrid/sampleprops.h | 18 +- src/propgrid/advprops.cpp | 84 ++++-- src/propgrid/editors.cpp | 96 +++++-- src/propgrid/property.cpp | 168 +++++++++--- src/propgrid/propgrid.cpp | 20 +- src/propgrid/propgridiface.cpp | 13 +- src/propgrid/propgridpagestate.cpp | 7 +- src/propgrid/props.cpp | 125 ++++----- 21 files changed, 1155 insertions(+), 431 deletions(-) diff --git a/include/wx/propgrid/advprops.h b/include/wx/propgrid/advprops.h index f5375997be..c27f7c5be2 100644 --- a/include/wx/propgrid/advprops.h +++ b/include/wx/propgrid/advprops.h @@ -136,7 +136,16 @@ public: const wxFont& value = wxFont()); virtual ~wxFontProperty() = default; virtual void OnSetValue() override; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual wxVariant ChildChanged( wxVariant& thisValue, int childIndex, wxVariant& childValue ) const override; @@ -168,23 +177,60 @@ public: virtual ~wxSystemColourProperty() = default; virtual void OnSetValue() override; - virtual bool IntToValue(wxVariant& variant, - int number, - int argFlags = 0) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use IntToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool IntToValue(wxVariant& variant, int number, + int flags) const override + { + m_oldIntToValueCalled = true; + return IntToValue(variant, number, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; // Override in derived class to customize how colours are printed as // strings. - virtual wxString ColourToString( const wxColour& col, int index, - int argFlags = 0 ) const; +#if WXWIN_COMPATIBILITY_3_2 + mutable bool m_oldColourToStringCalled = false; + wxString ColourToStringWithCheck(const wxColour& col, int index, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + wxDEPRECATED_BUT_USED_INTERNALLY_MSG("use ColourToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ColourToString(const wxColour& col, int index, + int flags) const + { + m_oldColourToStringCalled = true; + return ColourToString(col, index, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ColourToString(const wxColour& col, int index, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; // Returns index of entry that triggers colour picker dialog // (default is last). virtual int GetCustomColourIndex() const; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool OnEvent( wxPropertyGrid* propgrid, wxWindow* primary, wxEvent& event ) override; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ) override; @@ -240,7 +286,16 @@ public: const wxColour& value = *wxWHITE ); virtual ~wxColourProperty() = default; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual wxColour GetColour( int index ) const override; protected: @@ -262,7 +317,16 @@ class WXDLLIMPEXP_PROPGRID wxCursorProperty : public wxEnumProperty int value = 0 ); virtual ~wxCursorProperty() = default; - virtual wxString ValueToString(wxVariant& value, int argFlags = 0) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual wxSize OnMeasureImage( int item ) const override; virtual void OnCustomPaint( wxDC& dc, const wxRect& rect, wxPGPaintData& paintdata ) override; @@ -332,10 +396,27 @@ public: virtual ~wxMultiChoiceProperty() = default; virtual void OnSetValue() override; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue(wxVariant& variant, - const wxString& text, - int argFlags = 0) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ) override; wxArrayInt GetValueAsArrayInt() const @@ -382,10 +463,27 @@ public: virtual ~wxDateProperty() = default; virtual void OnSetValue() override; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue(wxVariant& variant, - const wxString& text, - int argFlags = 0) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ) override; diff --git a/include/wx/propgrid/property.h b/include/wx/propgrid/property.h index 076a0cc58e..0676e79c5f 100644 --- a/include/wx/propgrid/property.h +++ b/include/wx/propgrid/property.h @@ -1088,9 +1088,9 @@ public: // null wxVariant in normal cases). Translated value must be assigned // back to it. // text - Text to be translated into variant. - // argFlags - If wxPG_FULL_VALUE is set, returns complete, storable value instead + // flags - If wxPGPropValFormatFlags::FullValue is set, returns complete, storable value instead // of displayable one (they may be different). - // If wxPG_COMPOSITE_FRAGMENT is set, text is interpreted as a part of + // If wxPGPropValFormatFlags::CompositeFragment is set, text is interpreted as a part of // composite property string value (as generated by ValueToString() // called with this same flag). // Returns true if resulting wxVariant value was different. @@ -1099,9 +1099,19 @@ public: // You might want to take into account that m_value is Null variant // if property value is unspecified (which is usually only case if // you explicitly enabled that sort behaviour). - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; +#if WXWIN_COMPATIBILITY_3_2 + mutable bool m_oldStringToValueCalled = false; + bool StringToValueWithCheck(wxVariant& variant, const wxString& text, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + wxDEPRECATED_BUT_USED_INTERNALLY_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue( wxVariant& variant, const wxString& text, + int flags ) const + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; // Converts integer (possibly a choice selection) into wxVariant value // appropriate for this property. @@ -1109,7 +1119,7 @@ public: // variant - On function entry this is the old value (should not be null wxVariant // in normal cases). Translated value must be assigned back to it. // number - Integer to be translated into variant. - // argFlags - If wxPG_FULL_VALUE is set, returns complete, storable value + // flags - If wxPGPropValFormatFlags::FullValue is set, returns complete, storable value // instead of displayable one. // Returns true if resulting wxVariant value was different. // Remarks @@ -1122,36 +1132,69 @@ public: // - You might want to take into account that m_value is Null variant // if property value is unspecified (which is usually only case if // you explicitly enabled that sort behaviour). - virtual bool IntToValue( wxVariant& value, - int number, - int argFlags = 0 ) const; +#if WXWIN_COMPATIBILITY_3_2 + mutable bool m_oldIntToValueCalled = false; + bool IntToValueWithCheck(wxVariant& variant, int number, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + wxDEPRECATED_BUT_USED_INTERNALLY_MSG("use IntToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool IntToValue(wxVariant& value, int number, int flags) const + { + m_oldIntToValueCalled = true; + return IntToValue(value, number, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool IntToValue(wxVariant& value, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; // Converts property value into a text representation. // Parameters: // value - Value to be converted. - // argFlags - If 0 (default value), then displayed string is returned. - // If wxPG_FULL_VALUE is set, returns complete, storable string value - // instead of displayable. If wxPG_EDITABLE_VALUE is set, returns + // flags - If wxPGPropValFormatFlags::Null (default value), then displayed string is returned. + // If wxPGPropValFormatFlags::FullValue is set, returns complete, storable string value + // instead of displayable. If wxPGPropValFormatFlags::EditableValue is set, returns // string value that must be editable in textctrl. If - // wxPG_COMPOSITE_FRAGMENT is set, returns text that is appropriate to + // wxPGPropValFormatFlags::CompositeFragment is set, returns text that is appropriate to // display as a part of string property's composite text // representation. // Default implementation calls GenerateComposedValue(). - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; +#if WXWIN_COMPATIBILITY_3_2 + mutable bool m_oldValueToStringCalled = false; + wxString ValueToStringWithCheck(wxVariant& variant, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + wxDEPRECATED_BUT_USED_INTERNALLY_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; // Converts string to a value, and if successful, calls SetValue() on it. // Default behaviour is to do nothing. // Returns true if value was changed. - bool SetValueFromString( const wxString& text, int flags = wxPG_PROGRAMMATIC_VALUE ); +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use SetValueFromString with 'flags' argument as wxPGPropValFormatFlags") + bool SetValueFromString(const wxString& text, int flags) + { + return SetValueFromString(text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + bool SetValueFromString(const wxString& text, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::ProgrammaticValue); // Converts integer to a value, and if successful, calls SetValue() on it. // Default behaviour is to do nothing. // Parameters: // value - Int to get the value from. - // flags - If has wxPG_FULL_VALUE, then the value given is a actual value + // flags - If has wxPGPropValFormatFlags::FullValue, then the value given is a actual value // and not an index. // Returns true if value was changed. - bool SetValueFromInt( long value, int flags = 0 ); +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use SetValueFromInt with 'flags' argument as wxPGPropValFormatFlags") + bool SetValueFromInt(long value, int flags) + { + return SetValueFromInt(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + bool SetValueFromInt(long value, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null); // Returns size of the custom painted image in front of property. // This method must be overridden to return non-default value if @@ -1382,18 +1425,28 @@ public: } // Returns text representation of property's value. - // argFlags - If 0 (default value), then displayed string is returned. - // If wxPG_FULL_VALUE is set, returns complete, storable string value - // instead of displayable. If wxPG_EDITABLE_VALUE is set, returns + // flags - If wxPGPropValFormatFlags::Null (default value), then displayed string is returned. + // If wxPGPropValFormatFlags::FullValue is set, returns complete, storable string value + // instead of displayable. If wxPGPropValFormatFlags::EditableValue is set, returns // string value that must be editable in textctrl. If - // wxPG_COMPOSITE_FRAGMENT is set, returns text that is appropriate to + // wxPGPropValFormatFlags::CompositeFragment is set, returns text that is appropriate to // display as a part of string property's composite text // representation. // In older versions, this function used to be overridden to convert // property's value into a string representation. This function is // now handled by ValueToString(), and overriding this function now // will result in run-time assertion failure. - virtual wxString GetValueAsString( int argFlags = 0 ) const; +#if WXWIN_COMPATIBILITY_3_2 + mutable bool m_oldGetValueAsString = false; + wxString GetValueAsStringWithCheck(wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + wxDEPRECATED_BUT_USED_INTERNALLY_MSG("use GetValueAsString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString GetValueAsString(int flags) const + { + m_oldGetValueAsString = true; + return GetValueAsString(static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString GetValueAsString(wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; // Returns wxPGCell of given column. // Const version of this member function returns 'default' @@ -1416,7 +1469,12 @@ public: // Returns property's displayed text. wxString GetDisplayedString() const { - return GetValueAsString(0); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + return GetValueAsStringWithCheck(wxPGPropValFormatFlags::Null); +#else + return GetValueAsString(wxPGPropValFormatFlags::Null); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 } // Returns property's hint text (shown in empty value cell). @@ -2087,10 +2145,20 @@ protected: int index = -1, bool correct_mode = true ); - void DoGenerateComposedValue( wxString& text, - int argFlags = wxPG_VALUE_IS_CURRENT, - const wxVariantList* valueOverrides = nullptr, - wxPGHashMapS2S* childResults = nullptr ) const; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use DoGenerateComposedValue with 'flags' argument as wxPGPropValFormatFlags") + void DoGenerateComposedValue(wxString& text, int flags, + const wxVariantList* valueOverrides, + wxPGHashMapS2S* childResults) const + { + DoGenerateComposedValue(text, static_cast(flags), + valueOverrides, childResults); + } +#endif // WXWIN_COMPATIBILITY_3_2 + void DoGenerateComposedValue(wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::ValueIsCurrent, + const wxVariantList* valueOverrides = nullptr, + wxPGHashMapS2S* childResults = nullptr) const; bool DoHide( bool hide, wxPGPropertyValuesFlags flags ); @@ -2266,10 +2334,17 @@ public: wxPGRootProperty( const wxString& name = wxS("") ); virtual ~wxPGRootProperty() = default; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") virtual bool StringToValue( wxVariant&, const wxString&, int ) const override { return false; } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue( wxVariant&, const wxString&, wxPGPropValFormatFlags ) const override + { + return false; + } protected: }; @@ -2292,8 +2367,24 @@ public: int GetTextExtent( const wxWindow* wnd, const wxFont& font ) const; - virtual wxString ValueToString( wxVariant& value, int argFlags ) const override; - virtual wxString GetValueAsString( int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, wxPGPropValFormatFlags flags) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use GetValueAsString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString GetValueAsString(int flags) const override + { + m_oldGetValueAsString = true; + return GetValueAsString(static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString GetValueAsString(wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; protected: void SetTextColIndex( unsigned int colInd ) diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index 0dd0a0da89..06b070675a 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -1032,8 +1032,15 @@ public: // Returns (visual) text representation of the unspecified // property value. - // argFlags - For internal use only. - wxString GetUnspecifiedValueText( int argFlags = 0 ) const; + // flags - For internal use only. +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use GetUnspecifiedValueText with 'flags' argument as wxPGPropValFormatFlags") + wxString GetUnspecifiedValueText(int flags) const + { + return GetUnspecifiedValueText(static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + wxString GetUnspecifiedValueText(wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; // Set virtual width for this particular page. Width -1 indicates that the // virtual width should be disabled. diff --git a/include/wx/propgrid/propgriddefs.h b/include/wx/propgrid/propgriddefs.h index 6febe05ce3..0ee66de466 100644 --- a/include/wx/propgrid/propgriddefs.h +++ b/include/wx/propgrid/propgriddefs.h @@ -212,36 +212,93 @@ constexpr bool operator!=(wxPGPropertyValuesFlags a, int b) // ----------------------------------------------------------------------- -// Misc. argument flags. -enum wxPG_MISC_ARG_FLAGS +// Miscellaneous property value format flags +enum class wxPGPropValFormatFlags : int { + // No flags. + Null = 0, + // Get/Store full value instead of displayed value. - wxPG_FULL_VALUE = 0x00000001, + FullValue = 0x00000001, // Perform special action in case of unsuccessful conversion. - wxPG_REPORT_ERROR = 0x00000002, + ReportError = 0x00000002, - wxPG_PROPERTY_SPECIFIC = 0x00000004, + PropertySpecific = 0x00000004, // Get/Store editable value instead of displayed one (should only be // different in the case of common values) - wxPG_EDITABLE_VALUE = 0x00000008, + EditableValue = 0x00000008, // Used when dealing with fragments of composite string value - wxPG_COMPOSITE_FRAGMENT = 0x00000010, + CompositeFragment = 0x00000010, // Means property for which final string value is for cannot really be // edited. - wxPG_UNEDITABLE_COMPOSITE_FRAGMENT = 0x00000020, + UneditableCompositeFragment = 0x00000020, // ValueToString() called from GetValueAsString() // (guarantees that input wxVariant value is current own value) - wxPG_VALUE_IS_CURRENT = 0x00000040, + ValueIsCurrent = 0x00000040, // Value is being set programmatically (i.e. not by user) - wxPG_PROGRAMMATIC_VALUE = 0x00000080 + ProgrammaticValue = 0x00000080 }; +constexpr wxPGPropValFormatFlags operator&(wxPGPropValFormatFlags a, wxPGPropValFormatFlags b) +{ + return static_cast(static_cast(a) & static_cast(b)); +} + +constexpr wxPGPropValFormatFlags operator|(wxPGPropValFormatFlags a, wxPGPropValFormatFlags b) +{ + return static_cast(static_cast(a) | static_cast(b)); +} + +inline wxPGPropValFormatFlags operator|=(wxPGPropValFormatFlags& a, wxPGPropValFormatFlags b) +{ + return a = a | b; +} + +constexpr bool operator!(wxPGPropValFormatFlags a) +{ + return static_cast(a) == 0; +} + +#if WXWIN_COMPATIBILITY_3_2 +constexpr int operator&(int a, wxPGPropValFormatFlags b) +{ + return a & static_cast(b); +} + +constexpr int operator|(int a, wxPGPropValFormatFlags b) +{ + return a | static_cast(b); +} + +inline int operator|=(int& a, wxPGPropValFormatFlags b) +{ + return a = a | static_cast(b); +} + +wxDEPRECATED_MSG("use wxPGPropValFormatFlags::FullValue instead") +constexpr wxPGPropValFormatFlags wxPG_FULL_VALUE { wxPGPropValFormatFlags::FullValue }; +wxDEPRECATED_MSG("use wxPGPropValFormatFlags::ReportError instead") +constexpr wxPGPropValFormatFlags wxPG_REPORT_ERROR { wxPGPropValFormatFlags::ReportError }; +wxDEPRECATED_MSG("use wxPGPropValFormatFlags::PropertySpecific instead") +constexpr wxPGPropValFormatFlags wxPG_PROPERTY_SPECIFIC { wxPGPropValFormatFlags::PropertySpecific }; +wxDEPRECATED_MSG("use wxPGPropValFormatFlags::EditableValue instead") +constexpr wxPGPropValFormatFlags wxPG_EDITABLE_VALUE { wxPGPropValFormatFlags::EditableValue }; +wxDEPRECATED_MSG("use wxPGPropValFormatFlags::CompositeFragment instead") +constexpr wxPGPropValFormatFlags wxPG_COMPOSITE_FRAGMENT { wxPGPropValFormatFlags::CompositeFragment }; +wxDEPRECATED_MSG("use wxPGPropValFormatFlags::UneditableCompositeFragment instead") +constexpr wxPGPropValFormatFlags wxPG_UNEDITABLE_COMPOSITE_FRAGMENT { wxPGPropValFormatFlags::UneditableCompositeFragment }; +wxDEPRECATED_MSG("use wxPGPropValFormatFlags::ValueIsCurrent instead") +constexpr wxPGPropValFormatFlags wxPG_VALUE_IS_CURRENT { wxPGPropValFormatFlags::ValueIsCurrent }; +wxDEPRECATED_MSG("use wxPGPropValFormatFlags::ProgrammaticValue instead") +constexpr wxPGPropValFormatFlags wxPG_PROGRAMMATIC_VALUE { wxPGPropValFormatFlags::ProgrammaticValue }; +#endif // WXWIN_COMPATIBILITY_3_2 + // ----------------------------------------------------------------------- // wxPGProperty::SetValue() flags diff --git a/include/wx/propgrid/propgridiface.h b/include/wx/propgrid/propgridiface.h index 40a6c48fc3..ff392782bf 100644 --- a/include/wx/propgrid/propgridiface.h +++ b/include/wx/propgrid/propgridiface.h @@ -797,22 +797,22 @@ public: // Sets an attribute for this property. // name - Text identifier of attribute. See @ref propgrid_property_attributes. // value - Value of attribute. - // argFlags - Optional. Use wxPGPropertyValuesFlags::Recurse to set the attribute to child + // flags - Optional. Use wxPGPropertyValuesFlags::Recurse to set the attribute to child // properties recursively. // Setting attribute's value to null wxVariant will simply remove it // from property's set of attributes. #if WXWIN_COMPATIBILITY_3_2 - wxDEPRECATED_MSG("use SetPropertyAttribute with argFlags argument as wxPGPropertyValuesFlags") + wxDEPRECATED_MSG("use SetPropertyAttribute with 'flags' argument as wxPGPropertyValuesFlags") void SetPropertyAttribute(wxPGPropArg id, const wxString& attrName, - wxVariant value, long argFlags) + wxVariant value, long flags) { - DoSetPropertyAttribute(id, attrName, value, static_cast(argFlags)); + DoSetPropertyAttribute(id, attrName, value, static_cast(flags)); } #endif // WXWIN_COMPATIBILITY_3_2 void SetPropertyAttribute(wxPGPropArg id, const wxString& attrName, wxVariant value, - wxPGPropertyValuesFlags argFlags = wxPGPropertyValuesFlags::DontRecurse) + wxPGPropertyValuesFlags flags = wxPGPropertyValuesFlags::DontRecurse) { - DoSetPropertyAttribute(id, attrName, value, argFlags); + DoSetPropertyAttribute(id, attrName, value, flags); } // Sets property attribute for all applicable properties. // Be sure to use this method only after all properties have been @@ -1236,7 +1236,7 @@ protected: // Intermediate version needed due to wxVariant copying inefficiency void DoSetPropertyAttribute( wxPGPropArg id, const wxString& name, - wxVariant& value, wxPGPropertyValuesFlags argFlags ); + wxVariant& value, wxPGPropertyValuesFlags flags ); // Empty string object to return from member functions returning const // wxString&. diff --git a/include/wx/propgrid/props.h b/include/wx/propgrid/props.h index cdae89c8e0..29d4b6a0e6 100644 --- a/include/wx/propgrid/props.h +++ b/include/wx/propgrid/props.h @@ -99,10 +99,28 @@ public: const wxString& value = wxString() ); virtual ~wxStringProperty() = default; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; + +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue( wxVariant& variant, const wxString& text, + int flags ) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ) override; @@ -194,15 +212,39 @@ public: const wxString& name, const wxLongLong& value ); #endif - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const override; - virtual bool IntToValue( wxVariant& variant, - int number, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use IntToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool IntToValue(wxVariant& variant, int number, int flags) const override + { + m_oldIntToValueCalled = true; + return IntToValue(variant, number, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; static wxValidator* GetClassValidator(); virtual wxValidator* DoGetValidator() const override; virtual wxVariant AddSpinStepValue(long stepScale) const override; @@ -240,17 +282,42 @@ public: const wxString& name, const wxULongLong& value ); #endif - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ) override; virtual bool ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const override; virtual wxValidator* DoGetValidator () const override; - virtual bool IntToValue( wxVariant& variant, - int number, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use IntToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool IntToValue(wxVariant& variant, int number, + int flags) const override + { + m_oldIntToValueCalled = true; + return IntToValue(variant, number, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual wxVariant AddSpinStepValue(long stepScale) const override; protected: @@ -285,10 +352,27 @@ public: double value = 0.0 ); virtual ~wxFloatProperty() = default; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ) override; virtual bool ValidateValue( wxVariant& value, @@ -321,12 +405,37 @@ public: bool value = false ); virtual ~wxBoolProperty() = default; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const override; - virtual bool IntToValue( wxVariant& variant, - int number, int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use IntToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool IntToValue(wxVariant& variant, int number, int flags) const override + { + m_oldIntToValueCalled = true; + return IntToValue(variant, number, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ) override; }; @@ -387,18 +496,41 @@ public: size_t GetItemCount() const { return m_choices.GetCount(); } virtual void OnSetValue() override; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const override; - // If wxPG_FULL_VALUE is not set in flags, then the value is interpreted + // If wxPGPropValFormatFlags::FullValue is not set in flags, then the value is interpreted // as index to choices list. Otherwise, it is actual value. - virtual bool IntToValue( wxVariant& variant, - int number, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use IntToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool IntToValue(wxVariant& variant, int number, int flags) const override + { + m_oldIntToValueCalled = true; + return IntToValue(variant, number, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; // // Additional virtuals @@ -420,25 +552,38 @@ protected: wxDEPRECATED_MSG("use ValueFromString_(wxVariant&, int*, const wxString&, int) function instead") bool ValueFromString_( wxVariant& value, const wxString& text, - int argFlags ) const + int flags ) const { - return ValueFromString_(value, nullptr, text, argFlags); + return ValueFromString_(value, nullptr, text, static_cast(flags)); } wxDEPRECATED_MSG("use ValueFromInt_(wxVariant&, int*, int, int) function instead") - bool ValueFromInt_( wxVariant& value, int intVal, int argFlags ) const + bool ValueFromInt_( wxVariant& value, int intVal, int flags ) const { - return ValueFromInt_(value, nullptr, intVal, argFlags); + return ValueFromInt_(value, nullptr, intVal, static_cast(flags)); } wxDEPRECATED_MSG("don't use ResetNextIndex() function") static void ResetNextIndex() { } #endif // Converts text to value and returns corresponding index in the collection - bool ValueFromString_(wxVariant& value, - int* pIndex, - const wxString& text, - int argFlags) const; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueFromString_ with 'flags' argument as wxPGPropValFormatFlags") + bool ValueFromString_(wxVariant& value, int* pIndex, + const wxString& text, int flags) const + { + return ValueFromString_(value, pIndex, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + bool ValueFromString_(wxVariant& value, int* pIndex, + const wxString& text, wxPGPropValFormatFlags flags) const; // Converts number to value and returns corresponding index in the collection - bool ValueFromInt_(wxVariant& value, int* pIndex, int intVal, int argFlags) const; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueFromInt_ with 'flags' argument as wxPGPropValFormatFlags") + bool ValueFromInt_(wxVariant& value, int* pIndex, int intVal, int flags) const + { + return ValueFromInt_(value, pIndex, intVal, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + bool ValueFromInt_(wxVariant& value, int* pIndex, int intVal, wxPGPropValFormatFlags flags) const; private: // This is private so that classes are guaranteed to use GetIndex @@ -482,9 +627,17 @@ public: virtual ~wxEditEnumProperty() = default; void OnSetValue() override; - bool StringToValue(wxVariant& variant, - const wxString& text, - int argFlags = 0) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; bool ValidateValue(wxVariant& value, wxPGValidationInfo& validationInfo) const override; @@ -524,10 +677,27 @@ public: virtual ~wxFlagsProperty () = default; virtual void OnSetValue() override; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int flags ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags) const override; virtual wxVariant ChildChanged( wxVariant& thisValue, int childIndex, wxVariant& childValue ) const override; @@ -597,10 +767,26 @@ public: virtual ~wxFileProperty() = default; virtual void OnSetValue() override; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ) override; static wxValidator* GetClassValidator(); @@ -639,10 +825,27 @@ public: const wxString& value = wxString() ); virtual ~wxLongStringProperty() = default; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; protected: virtual bool DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& value) override; @@ -661,9 +864,27 @@ public: const wxString& value = wxString() ); virtual ~wxDirProperty() = default; - virtual wxString ValueToString(wxVariant& value, int argFlags = 0) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") virtual bool StringToValue(wxVariant& variant, const wxString& text, - int argFlags = 0) const override; + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; #if WXWIN_COMPATIBILITY_3_0 virtual bool DoSetAttribute(const wxString& name, wxVariant& value) override; #endif // WXWIN_COMPATIBILITY_3_0 @@ -686,10 +907,27 @@ public: virtual ~wxArrayStringProperty() = default; virtual void OnSetValue() override; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use ValueToString with 'flags' argument as wxPGPropValFormatFlags") + virtual wxString ValueToString(wxVariant& value, int flags) const override + { + m_oldValueToStringCalled = true; + return ValueToString(value, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use StringToValue with 'flags' argument as wxPGPropValFormatFlags") + virtual bool StringToValue(wxVariant& variant, const wxString& text, + int flags) const override + { + m_oldStringToValueCalled = true; + return StringToValue(variant, text, static_cast(flags)); + } +#endif // WXWIN_COMPATIBILITY_3_2 + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ) override; // Implement in derived class for custom array-to-string conversion. diff --git a/interface/wx/propgrid/advprops.h b/interface/wx/propgrid/advprops.h index 15f3791282..38f07dc746 100644 --- a/interface/wx/propgrid/advprops.h +++ b/interface/wx/propgrid/advprops.h @@ -77,7 +77,8 @@ public: const wxFont& value = wxFont()); virtual ~wxFontProperty(); virtual void OnSetValue(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual wxVariant ChildChanged( wxVariant& thisValue, int childIndex, wxVariant& childValue ) const; @@ -107,26 +108,24 @@ public: virtual ~wxSystemColourProperty(); virtual void OnSetValue(); - virtual bool IntToValue(wxVariant& variant, - int number, - int argFlags = 0) const; + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; - /** - Override in derived class to customize how colours are printed as + /** Override in derived class to customize how colours are printed as strings. */ - virtual wxString ColourToString( const wxColour& col, int index, - int argFlags = 0 ) const; + virtual wxString ColourToString(const wxColour& col, int index, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; /** Returns index of entry that triggers colour picker dialog (default is last). */ virtual int GetCustomColourIndex() const; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool OnEvent( wxPropertyGrid* propgrid, wxWindow* primary, wxEvent& event ); virtual bool DoSetAttribute( const wxString& name, wxVariant& value ); @@ -134,7 +133,8 @@ public: virtual void OnCustomPaint( wxDC& dc, const wxRect& rect, wxPGPaintData& paintdata ); - // Helper function to show the colour dialog + /** Helper function to show the colour dialog + */ bool QueryColourFromUser( wxVariant& variant ) const; /** Default is to use wxSystemSettings::GetColour(index). Override to use @@ -184,7 +184,8 @@ public: const wxColour& value = *wxWHITE ); virtual ~wxColourProperty(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual wxColour GetColour( int index ) const; protected: @@ -205,6 +206,8 @@ public: int value = 0 ); virtual ~wxCursorProperty(); + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual wxSize OnMeasureImage( int item ) const; virtual void OnCustomPaint( wxDC& dc, const wxRect& rect, wxPGPaintData& paintdata ); @@ -279,10 +282,10 @@ public: virtual ~wxMultiChoiceProperty(); virtual void OnSetValue(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue(wxVariant& variant, - const wxString& text, - int argFlags = 0) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; wxArrayInt GetValueAsArrayInt() const; @@ -322,10 +325,10 @@ public: virtual ~wxDateProperty(); virtual void OnSetValue(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue(wxVariant& variant, - const wxString& text, - int argFlags = 0) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ); diff --git a/interface/wx/propgrid/property.h b/interface/wx/propgrid/property.h index 191a2fc729..e86656fd88 100644 --- a/interface/wx/propgrid/property.h +++ b/interface/wx/propgrid/property.h @@ -822,12 +822,12 @@ enum class wxPGPropertyFlags : int } virtual wxString ValueToString( wxVariant& value, - int argFlags ) const + int flags ) const { // TODO: Convert given property value to a string } - virtual bool StringToValue( wxVariant& variant, const wxString& text, int argFlags ) + virtual bool StringToValue( wxVariant& variant, const wxString& text, int flags ) { // TODO: Adapt string to property value. } @@ -909,12 +909,12 @@ public: @param text Text to be translated into variant. - @param argFlags - If ::wxPG_FULL_VALUE is set, returns complete, storable value instead - of displayable one (they may be different). - If ::wxPG_COMPOSITE_FRAGMENT is set, text is interpreted as a part of - composite property string value (as generated by ValueToString() - called with this same flag). + @param flags + If wxPGPropValFormatFlags::FullValue is set, returns complete, storable value + instead of displayable one (they may be different). + If wxPGPropValFormatFlags::CompositeFragment is set, text is interpreted as + a part of composite property string value (as generated by + ValueToString() called with this same flag). @return Returns @true if resulting wxVariant value was different. @@ -925,7 +925,8 @@ public: if property value is unspecified (which is usually only case if you explicitly enabled that sort behaviour). */ - virtual bool StringToValue( wxVariant& variant, const wxString& text, int argFlags = 0 ) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; /** Converts integer (possibly a choice selection) into wxVariant value @@ -936,9 +937,9 @@ public: in normal cases). Translated value must be assigned back to it. @param number Integer to be translated into variant. - @param argFlags - If ::wxPG_FULL_VALUE is set, returns complete, storable value instead - of displayable one. + @param flags + If wxPGPropValFormatFlags::FullValue is set, returns complete, storable value + instead of displayable one. @return Returns @true if resulting wxVariant value was different. @@ -953,24 +954,25 @@ public: property value is unspecified (which is usually only case if you explicitly enabled that sort behaviour). */ - virtual bool IntToValue( wxVariant& variant, int number, int argFlags = 0 ) const; + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; /** Converts property value into a text representation. @param value Value to be converted. - @param argFlags - If 0 (default value), then displayed string is returned. - If ::wxPG_FULL_VALUE is set, returns complete, storable string value - instead of displayable. If ::wxPG_EDITABLE_VALUE is set, returns + @param flags + If wxPGPropValFormatFlags::Null (default value), then displayed string is returned. + If wxPGPropValFormatFlags::FullValue is set, returns complete, storable string value + instead of displayable. If wxPGPropValFormatFlags::EditableValue is set, returns string value that must be editable in textctrl. - If ::wxPG_COMPOSITE_FRAGMENT is set, returns text that is appropriate to + If wxPGPropValFormatFlags::CompositeFragment is set, returns text that is appropriate to display as a part of string property's composite text representation. @remarks Default implementation calls GenerateComposedValue(). */ - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; /** Converts string to a value, and if successful, calls SetValue() on it. @@ -979,18 +981,19 @@ public: @param text String to get the value from. @param flags - If ::wxPG_FULL_VALUE is set, the function sets complete, storable + If wxPGPropValFormatFlags::FullValue is set, the function sets complete, storable value instead of displayable one (they may be different). - ::wxPG_PROGRAMMATIC_VALUE flag is used to indicate that value is + wxPGPropValFormatFlags::ProgrammaticValue flag is used to indicate that value is being set programmatically (i.e. operation is not caused by user input). - If ::wxPG_REPORT_ERROR is set, a special action should be + If wxPGPropValFormatFlags::ReportError is set, a special action should be performed if string couldn't have been successfully converted to the valid value (e.g. a special value can be set in this case). @return @true if value was changed. */ - bool SetValueFromString( const wxString& text, int flags = wxPG_PROGRAMMATIC_VALUE ); + bool SetValueFromString(const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::ProgrammaticValue); /** Converts integer to a value, and if successful, calls SetValue() on it. @@ -999,11 +1002,11 @@ public: @param value Int to get the value from. @param flags - If has ::wxPG_FULL_VALUE, then the value given is an actual value and not an index. + If has wxPGPropValFormatFlags::FullValue, then the value given is an actual value and not an index. @return @true if value was changed. */ - bool SetValueFromInt( long value, int flags = 0 ); + bool SetValueFromInt(long value, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null); /** Returns size of the custom painted image in front of property. This method @@ -1613,12 +1616,12 @@ public: /** Returns text representation of property's value. - @param argFlags - If 0 (default value), then displayed string is returned. - If ::wxPG_FULL_VALUE is set, returns complete, storable string value - instead of displayable. If ::wxPG_EDITABLE_VALUE is set, returns + @param flags + If wxPGPropValFormatFlags::Null (default value), then displayed string is returned. + If wxPGPropValFormatFlags::FullValue is set, returns complete, storable string value + instead of displayable. If wxPGPropValFormatFlags::EditableValue is set, returns string value that must be editable in textctrl. If - ::wxPG_COMPOSITE_FRAGMENT is set, returns text that is appropriate to + wxPGPropValFormatFlags::CompositeFragment is set, returns text that is appropriate to display as a part of string property's composite text representation. @@ -1627,15 +1630,7 @@ public: now handled by ValueToString(), and overriding this function now will result in run-time assertion failure. */ - virtual wxString GetValueAsString( int argFlags = 0 ) const; - - /** Synonymous to GetValueAsString(). - - @deprecated Use GetValueAsString() instead. - - @see GetValueAsString() - */ - wxString GetValueString( int argFlags = 0 ) const; + virtual wxString GetValueAsString(wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; /** Returns value type used by this property. @@ -2923,7 +2918,7 @@ public: wxPGRootProperty( const wxString& name = wxS("") ); virtual ~wxPGRootProperty(); - virtual bool StringToValue( wxVariant&, const wxString&, int ) const; + virtual bool StringToValue( wxVariant&, const wxString&, wxPGPropValFormatFlags ) const; }; // ----------------------------------------------------------------------- @@ -2942,10 +2937,10 @@ public: wxPropertyCategory( const wxString& label, const wxString& name = wxPG_LABEL ); - ~wxPropertyCategory(); + virtual ~wxPropertyCategory(); int GetTextExtent( const wxWindow* wnd, const wxFont& font ) const; - virtual wxString ValueToString( wxVariant& value, int argFlags ) const; - virtual wxString GetValueAsString( int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, wxPGPropValFormatFlags flags) const; + virtual wxString GetValueAsString(wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; }; diff --git a/interface/wx/propgrid/propgrid.h b/interface/wx/propgrid/propgrid.h index 29c1e25cbb..c68fda75c8 100644 --- a/interface/wx/propgrid/propgrid.h +++ b/interface/wx/propgrid/propgrid.h @@ -851,9 +851,9 @@ public: Returns (visual) text representation of the unspecified property value. - @param argFlags For internal use only. + @param flags For internal use only. */ - wxString GetUnspecifiedValueText( int argFlags = 0 ) const; + wxString GetUnspecifiedValueText(wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; /** Returns current vertical spacing. diff --git a/interface/wx/propgrid/propgriddefs.h b/interface/wx/propgrid/propgriddefs.h index 23314b4411..259c5ff1d2 100644 --- a/interface/wx/propgrid/propgriddefs.h +++ b/interface/wx/propgrid/propgriddefs.h @@ -105,52 +105,57 @@ enum class wxPGPropertyValuesFlags : int // ----------------------------------------------------------------------- -/** Misc argument flags. +/** Miscellaneous property value format flags. */ -enum wxPG_MISC_ARG_FLAGS +enum class wxPGPropValFormatFlags : int { + /** No flags. + @hideinitializer + */ + Null = 0, + /** Get/Store full value instead of displayed value. @hideinitializer */ - wxPG_FULL_VALUE = 0x00000001, + FullValue = 0x00000001, /** Perform special action in case of unsuccessful conversion. @hideinitializer */ - wxPG_REPORT_ERROR = 0x00000002, + ReportError = 0x00000002, /** @hideinitializer */ - wxPG_PROPERTY_SPECIFIC = 0x00000004, + PropertySpecific = 0x00000004, /** Get/Store editable value instead of displayed one (should only be different in the case of common values). @hideinitializer */ - wxPG_EDITABLE_VALUE = 0x00000008, + EditableValue = 0x00000008, /** Used when dealing with fragments of composite string value @hideinitializer */ - wxPG_COMPOSITE_FRAGMENT = 0x00000010, + CompositeFragment = 0x00000010, /** Means property for which final string value is for cannot really be edited. @hideinitializer */ - wxPG_UNEDITABLE_COMPOSITE_FRAGMENT = 0x00000020, + UneditableCompositeFragment = 0x00000020, /** wxPGProperty::ValueToString() called from wxPGProperty::GetValueAsString() (guarantees that input wxVariant value is current own value) @hideinitializer */ - wxPG_VALUE_IS_CURRENT = 0x00000040, + ValueIsCurrent = 0x00000040, /** Value is being set programmatically (i.e. not by user) @hideinitializer */ - wxPG_PROGRAMMATIC_VALUE = 0x00000080 + ProgrammaticValue = 0x00000080 }; // ----------------------------------------------------------------------- diff --git a/interface/wx/propgrid/propgridiface.h b/interface/wx/propgrid/propgridiface.h index acbb9a4263..73eada045a 100644 --- a/interface/wx/propgrid/propgridiface.h +++ b/interface/wx/propgrid/propgridiface.h @@ -844,7 +844,7 @@ public: Text identifier of attribute. See @ref propgrid_property_attributes. @param value Value of attribute. - @param argFlags + @param flags Optional. Use wxPGPropertyValuesFlags::Recurse to set the attribute to child properties recursively. @@ -855,7 +855,7 @@ public: - Property is refreshed with new settings. */ void SetPropertyAttribute(wxPGPropArg id, const wxString& attrName, wxVariant value, - wxPGPropertyValuesFlags argFlags = wxPGPropertyValuesFlags::DontRecurse); + wxPGPropertyValuesFlags flags = wxPGPropertyValuesFlags::DontRecurse); /** Sets property attribute for all applicable properties. diff --git a/interface/wx/propgrid/props.h b/interface/wx/propgrid/props.h index c5ac027f96..34a8ff9426 100644 --- a/interface/wx/propgrid/props.h +++ b/interface/wx/propgrid/props.h @@ -48,10 +48,10 @@ public: const wxString& value = wxString() ); virtual ~wxStringProperty(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ); @@ -215,15 +215,14 @@ public: wxIntProperty( const wxString& label, const wxString& name, const wxLongLong& value ); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlagsflags = wxPGPropValFormatFlags::Null) const; virtual bool ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const; - virtual bool IntToValue( wxVariant& variant, - int number, - int argFlags = 0 ) const; + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; static wxValidator* GetClassValidator(); virtual wxValidator* DoGetValidator() const; virtual wxVariant AddSpinStepValue(long stepScale) const; @@ -260,17 +259,16 @@ public: wxUIntProperty( const wxString& label, const wxString& name, const wxULongLong& value ); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ); virtual bool ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const; virtual wxValidator* DoGetValidator () const; - virtual bool IntToValue( wxVariant& variant, - int number, - int argFlags = 0 ) const; + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual wxVariant AddSpinStepValue(long stepScale) const; protected: @@ -299,10 +297,10 @@ public: double value = 0.0 ); virtual ~wxFloatProperty(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ); virtual bool ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const; @@ -335,12 +333,12 @@ public: bool value = false ); virtual ~wxBoolProperty(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; - virtual bool IntToValue( wxVariant& variant, - int number, int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ); }; @@ -389,18 +387,18 @@ public: size_t GetItemCount() const; virtual void OnSetValue(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const; - // If wxPG_FULL_VALUE is not set in flags, then the value is interpreted - // as index to choices list. Otherwise, it is actual value. - virtual bool IntToValue( wxVariant& variant, - int number, - int argFlags = 0 ) const; + /** If wxPGPropValFormatFlags::FullValue is not set in flags, then the value is interpreted + as index to choices list. Otherwise, it is actual value. + */ + virtual bool IntToValue(wxVariant& variant, int number, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; // // Additional virtuals @@ -418,13 +416,10 @@ protected: int GetIndex() const; void SetIndex( int index ); - bool ValueFromString_( wxVariant& value, - const wxString& text, - int argFlags ) const; - bool ValueFromInt_( wxVariant& value, int intVal, int argFlags ) const; - - static void ResetNextIndex(); - + bool ValueFromString_(wxVariant& value, int* pIndex, const wxString& text, + wxPGPropValFormatFlags flags) const; + bool ValueFromInt_(wxVariant& value, int* pIndex, int intVal, + wxPGPropValFormatFlags flags) const; }; @@ -468,6 +463,11 @@ public: virtual ~wxEditEnumProperty(); + void OnSetValue() override; + bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + bool ValidateValue(wxVariant& value, + wxPGValidationInfo& validationInfo) const; }; @@ -506,10 +506,10 @@ public: virtual ~wxFlagsProperty (); virtual void OnSetValue(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int flags ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags) const; virtual wxVariant ChildChanged( wxVariant& thisValue, int childIndex, wxVariant& childValue ) const; @@ -602,10 +602,10 @@ public: virtual ~wxFileProperty (); virtual void OnSetValue(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ); static wxValidator* GetClassValidator(); @@ -643,10 +643,10 @@ public: const wxString& value = wxString() ); virtual ~wxLongStringProperty(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; protected: virtual bool DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& value); @@ -669,9 +669,10 @@ public: const wxString& value = wxString() ); virtual ~wxDirProperty(); - virtual wxString ValueToString(wxVariant& value, int argFlags = 0) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool StringToValue(wxVariant& variant, const wxString& text, - int argFlags = 0) const; + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual wxValidator* DoGetValidator() const; protected: @@ -696,10 +697,10 @@ public: virtual ~wxArrayStringProperty(); virtual void OnSetValue(); - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const; - virtual bool StringToValue( wxVariant& variant, - const wxString& text, - int argFlags = 0 ) const; + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; + virtual bool StringToValue(wxVariant& variant, const wxString& text, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ); /** diff --git a/samples/propgrid/sampleprops.cpp b/samples/propgrid/sampleprops.cpp index 986e4eafc2..442cd5e363 100644 --- a/samples/propgrid/sampleprops.cpp +++ b/samples/propgrid/sampleprops.cpp @@ -505,11 +505,11 @@ void wxArrayDoubleProperty::OnSetValue() } wxString wxArrayDoubleProperty::ValueToString( wxVariant& value, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { wxString s; - if ( argFlags & wxPG_FULL_VALUE ) + if ( !!(flags & wxPGPropValFormatFlags::FullValue) ) { GenerateValueAsString(s,-1,false); } @@ -571,7 +571,7 @@ bool wxArrayDoubleProperty::DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& v return false; } -bool wxArrayDoubleProperty::StringToValue( wxVariant& variant, const wxString& text, int ) const +bool wxArrayDoubleProperty::StringToValue( wxVariant& variant, const wxString& text, wxPGPropValFormatFlags ) const { // Add values to a temporary array so that in case // of error we can opt not to use them. @@ -707,12 +707,12 @@ wxColour MyColourProperty::GetColour(int index) const return wxColour(); } -wxString MyColourProperty::ColourToString(const wxColour& col, int index, int argFlags) const +wxString MyColourProperty::ColourToString(const wxColour& col, int index, wxPGPropValFormatFlags flags) const { if ( index == (int)(m_choices.GetCount() - 1) ) return wxEmptyString; - return wxColourProperty::ColourToString(col, index, argFlags); + return wxColourProperty::ColourToString(col, index, flags); } int MyColourProperty::GetCustomColourIndex() const diff --git a/samples/propgrid/sampleprops.h b/samples/propgrid/sampleprops.h index 3fa44c1d6e..32927038d2 100644 --- a/samples/propgrid/sampleprops.h +++ b/samples/propgrid/sampleprops.h @@ -116,10 +116,16 @@ public: virtual ~wxArrayDoubleProperty() = default; virtual void OnSetValue() override; - virtual wxString ValueToString( wxVariant& value, int argFlags = 0 ) const override; +#if WXWIN_COMPATIBILITY_3_2 + // To prevent warnings that obsolete methods are hidden by overloads with new signature. + using wxEditorDialogProperty::ValueToString; + using wxEditorDialogProperty::StringToValue; +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ValueToString(wxVariant& value, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual bool StringToValue( wxVariant& variant, const wxString& text, - int argFlags = 0 ) const override; + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null ) const override; virtual bool DoSetAttribute( const wxString& name, wxVariant& value ) override; // Generates cache for displayed text @@ -150,8 +156,12 @@ public: virtual wxColour GetColour(int index) const override; - virtual wxString ColourToString(const wxColour& col, - int index, int argFlags = 0) const override; +#if WXWIN_COMPATIBILITY_3_2 + // To prevent warning that obsolete method is hidden by overload with new signature. + using wxColourProperty::ColourToString; +#endif // WXWIN_COMPATIBILITY_3_2 + virtual wxString ColourToString(const wxColour& col, int index, + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const override; virtual int GetCustomColourIndex() const override; }; diff --git a/src/propgrid/advprops.cpp b/src/propgrid/advprops.cpp index 2085242197..2728a7f55d 100644 --- a/src/propgrid/advprops.cpp +++ b/src/propgrid/advprops.cpp @@ -334,7 +334,12 @@ bool wxPGSpinCtrlEditor::OnEvent(wxPropertyGrid* propgrid, wxPGProperty* propert stepScale *= spins; wxVariant v = prop->AddSpinStepValue(stepScale); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + SetControlStringValue(prop, propgrid->GetEditorControl(), prop->ValueToStringWithCheck(v)); +#else SetControlStringValue(prop, propgrid->GetEditorControl(), prop->ValueToString(v)); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 return true; } } @@ -579,7 +584,7 @@ wxFontProperty::wxFontProperty( const wxString& label, const wxString& name, wxPGProperty* p = new wxEnumProperty(_("Face Name"), wxS("Face Name"), *wxPGGlobalVars->m_fontFamilyChoices); - p->SetValueFromString(faceName, wxPG_FULL_VALUE); + p->SetValueFromString(faceName, wxPGPropValFormatFlags::FullValue); AddPrivateChild( p ); @@ -615,9 +620,9 @@ void wxFontProperty::OnSetValue() } wxString wxFontProperty::ValueToString( wxVariant& value, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { - return wxEditorDialogProperty::ValueToString(value, argFlags); + return wxEditorDialogProperty::ValueToString(value, flags); } bool wxFontProperty::DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& value) @@ -652,7 +657,7 @@ void wxFontProperty::RefreshChildren() wxFont font; font << m_value; Item(0)->SetValue( (long)font.GetPointSize() ); - Item(1)->SetValueFromString( font.GetFaceName(), wxPG_FULL_VALUE ); + Item(1)->SetValueFromString( font.GetFaceName(), wxPGPropValFormatFlags::FullValue ); Item(2)->SetValue( (long)font.GetStyle() ); Item(3)->SetValue( (long)font.GetWeight() ); Item(4)->SetValue( font.GetUnderlined() ); @@ -1054,15 +1059,35 @@ wxColour wxSystemColourProperty::GetColour( int index ) const return wxSystemSettings::GetColour( (wxSystemColour)index ); } +#if WXWIN_COMPATIBILITY_3_2 +// By call to obsolete function we want to check if user-overriden function is still in use +wxString wxSystemColourProperty::ColourToStringWithCheck(const wxColour& col, int index, + wxPGPropValFormatFlags flags) const +{ + m_oldColourToStringCalled = false; + wxString res = ColourToString(col, index, static_cast(flags)); + if ( m_oldColourToStringCalled ) + { + // Our own function was called - this implies that call was forwarded to the new overriding + // function and there is no need to call it explicitly. + } + else + { // User-overriden obsolete function was called + wxFAIL_MSG(wxString::Format("in %s use ColourToString with 'flags' argument as wxPGPropValFormatFlags", GetClassInfo()->GetClassName())); + } + return res; +} +#endif // WXWIN_COMPATIBILITY_3_2 + wxString wxSystemColourProperty::ColourToString( const wxColour& col, int index, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { if ( index == wxNOT_FOUND ) { - if ( (argFlags & wxPG_FULL_VALUE) || !!(m_flags & wxPGPropertyFlags_ColourHasAlpha) ) + if ( !!(flags & wxPGPropValFormatFlags::FullValue) || !!(m_flags & wxPGPropertyFlags_ColourHasAlpha) ) { return wxString::Format(wxS("(%i,%i,%i,%i)"), (int)col.Red(), @@ -1085,15 +1110,15 @@ wxString wxSystemColourProperty::ColourToString( const wxColour& col, } wxString wxSystemColourProperty::ValueToString( wxVariant& value, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { wxColourPropertyValue val = GetVal(&value); int index; - if ( argFlags & wxPG_VALUE_IS_CURRENT ) + if ( !!(flags & wxPGPropValFormatFlags::ValueIsCurrent) ) { - // GetIndex() only works reliably if wxPG_VALUE_IS_CURRENT flag is set, + // GetIndex() only works reliably if wxPGPropValFormatFlags::ValueIsCurrent flag is set, // but we should use it whenever possible. index = GetIndex(); @@ -1108,7 +1133,12 @@ wxString wxSystemColourProperty::ValueToString( wxVariant& value, index = m_choices.Index(val.m_type); } - return ColourToString(val.m_colour, index, argFlags); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + return ColourToStringWithCheck(val.m_colour, index, flags); +#else + return ColourToString(val.m_colour, index, flags); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 } @@ -1167,14 +1197,14 @@ bool wxSystemColourProperty::QueryColourFromUser( wxVariant& variant ) const } -bool wxSystemColourProperty::IntToValue( wxVariant& variant, int number, int argFlags ) const +bool wxSystemColourProperty::IntToValue( wxVariant& variant, int number, wxPGPropValFormatFlags flags ) const { int index = number; const int type = m_choices.GetValue(index); if ( type == wxPG_COLOUR_CUSTOM ) { - if ( !(argFlags & wxPG_PROPERTY_SPECIFIC) ) + if ( !(flags & wxPGPropValFormatFlags::PropertySpecific) ) return QueryColourFromUser(variant); // Call from event handler. @@ -1341,7 +1371,7 @@ void wxSystemColourProperty::OnCustomPaint( wxDC& dc, const wxRect& rect, } -bool wxSystemColourProperty::StringToValue( wxVariant& value, const wxString& text, int argFlags ) const +bool wxSystemColourProperty::StringToValue( wxVariant& value, const wxString& text, wxPGPropValFormatFlags flags ) const { const int custIndex = GetCustomColourIndex(); wxString custColName; @@ -1391,7 +1421,7 @@ bool wxSystemColourProperty::StringToValue( wxVariant& value, const wxString& te !(m_flags & wxPGPropertyFlags_HideCustomColour) && isCustomColour ) { - if ( !(argFlags & wxPG_EDITABLE_VALUE )) + if ( !(flags & wxPGPropValFormatFlags::EditableValue )) { // This really should not occur... // wxASSERT(false); @@ -1400,7 +1430,7 @@ bool wxSystemColourProperty::StringToValue( wxVariant& value, const wxString& te if ( !QueryColourFromUser(value) ) { - if ( !(argFlags & wxPG_PROPERTY_SPECIFIC) ) + if ( !(flags & wxPGPropValFormatFlags::PropertySpecific) ) return false; // If query for value comes from the event handler // use current pending value to be processed later on in OnEvent(). @@ -1417,7 +1447,7 @@ bool wxSystemColourProperty::StringToValue( wxVariant& value, const wxString& te { // Try predefined colour first int index; - bool res = ValueFromString_(value, &index, colStr, argFlags); + bool res = ValueFromString_(value, &index, colStr, flags); if ( res && index >= 0 ) { val.m_type = index; @@ -1601,15 +1631,15 @@ void wxColourProperty::Init( wxColour colour ) } wxString wxColourProperty::ValueToString( wxVariant& value, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { const wxPGEditor* editor = GetEditorClass(); if ( editor != wxPGEditor_Choice && editor != wxPGEditor_ChoiceAndButton && editor != wxPGEditor_ComboBox ) - argFlags |= wxPG_PROPERTY_SPECIFIC; + flags |= wxPGPropValFormatFlags::PropertySpecific; - return wxSystemColourProperty::ValueToString(value, argFlags); + return wxSystemColourProperty::ValueToString(value, flags); } wxColour wxColourProperty::GetColour( int index ) const @@ -1711,9 +1741,9 @@ wxCursorProperty::wxCursorProperty( const wxString& label, const wxString& name, m_flags |= wxPGPropertyFlags_StaticChoices; // Cursor selection cannot be changed. } -wxString wxCursorProperty::ValueToString(wxVariant& value, int argFlags) const +wxString wxCursorProperty::ValueToString(wxVariant& value, wxPGPropValFormatFlags flags) const { - return wxGetTranslation(wxEnumProperty::ValueToString(value, argFlags), + return wxGetTranslation(wxEnumProperty::ValueToString(value, flags), wxString(), "system cursor name"); } @@ -1945,10 +1975,10 @@ void wxMultiChoiceProperty::OnSetValue() } wxString wxMultiChoiceProperty::ValueToString( wxVariant& value, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { // If possible, use cached string - if ( argFlags & wxPG_VALUE_IS_CURRENT ) + if ( !!(flags & wxPGPropValFormatFlags::ValueIsCurrent) ) return m_display; return GenerateValueAsString(value); @@ -2058,7 +2088,7 @@ bool wxMultiChoiceProperty::DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& v return false; } -bool wxMultiChoiceProperty::StringToValue( wxVariant& variant, const wxString& text, int ) const +bool wxMultiChoiceProperty::StringToValue( wxVariant& variant, const wxString& text, wxPGPropValFormatFlags ) const { wxArrayString arr; @@ -2135,7 +2165,7 @@ void wxDateProperty::OnSetValue() } bool wxDateProperty::StringToValue( wxVariant& variant, const wxString& text, - int WXUNUSED(argFlags) ) const + wxPGPropValFormatFlags WXUNUSED(flags) ) const { wxDateTime dt; @@ -2153,7 +2183,7 @@ bool wxDateProperty::StringToValue( wxVariant& variant, const wxString& text, } wxString wxDateProperty::ValueToString( wxVariant& value, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { wxDateTime dateTime = value.GetDateTime(); @@ -2172,7 +2202,7 @@ wxString wxDateProperty::ValueToString( wxVariant& value, wxString format; if ( !m_format.empty() && - !(argFlags & wxPG_FULL_VALUE) ) + !(flags & wxPGPropValFormatFlags::FullValue) ) format = m_format; // Determine default from locale diff --git a/src/propgrid/editors.cpp b/src/propgrid/editors.cpp index de9f230bf3..9dfc565e5f 100644 --- a/src/propgrid/editors.cpp +++ b/src/propgrid/editors.cpp @@ -191,8 +191,13 @@ void wxPGEditor::SetControlAppearance( wxPropertyGrid* pg, } else if ( oCell.HasText() ) { +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + tcText = property->GetValueAsStringWithCheck( +#else tcText = property->GetValueAsString( - property->HasFlag(wxPGPropertyFlags::ReadOnly)?0:wxPG_EDITABLE_VALUE); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 + property->HasFlag(wxPGPropertyFlags::ReadOnly)?wxPGPropValFormatFlags::Null:wxPGPropValFormatFlags::EditableValue); changeText = true; } @@ -284,11 +289,16 @@ wxPGWindowList wxPGTextCtrlEditor::CreateControls( wxPropertyGrid* propGrid, property->HasAnyChild() ) return nullptr; - int argFlags = 0; + wxPGPropValFormatFlags fmtFlags = wxPGPropValFormatFlags::Null; if ( !property->HasFlag(wxPGPropertyFlags::ReadOnly) && !property->IsValueUnspecified() ) - argFlags |= wxPG_EDITABLE_VALUE; - text = property->GetValueAsString(argFlags); + fmtFlags |= wxPGPropValFormatFlags::EditableValue; +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + text = property->GetValueAsStringWithCheck(fmtFlags); +#else + text = property->GetValueAsString(fmtFlags); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 int flags = 0; if ( property->HasFlag(wxPGPropertyFlags_Password) && @@ -330,7 +340,12 @@ void wxPGTextCtrlEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl ) wxString s; if ( tc->HasFlag(wxTE_PASSWORD) ) - s = property->GetValueAsString(wxPG_FULL_VALUE); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + s = property->GetValueAsStringWithCheck(wxPGPropValFormatFlags::FullValue); +#else + s = property->GetValueAsString(wxPGPropValFormatFlags::FullValue); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 else s = property->GetDisplayedString(); @@ -397,7 +412,12 @@ bool wxPGTextCtrlEditor::GetTextCtrlValueFromControl( wxVariant& variant, wxPGPr return true; } - bool res = property->StringToValue(variant, textVal, wxPG_EDITABLE_VALUE); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + bool res = property->StringToValueWithCheck(variant, textVal, wxPGPropValFormatFlags::EditableValue); +#else + bool res = property->StringToValue(variant, textVal, wxPGPropValFormatFlags::EditableValue); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 // Changing unspecified always causes event (returning // true here should be enough to trigger it). @@ -435,9 +455,14 @@ void wxPGTextCtrlEditor_OnFocus( wxPGProperty* property, { // Make sure there is correct text (instead of unspecified value // indicator or hint text) - int flags = property->HasFlag(wxPGPropertyFlags::ReadOnly) ? - 0 : wxPG_EDITABLE_VALUE; - wxString correctText = property->GetValueAsString(flags); + wxPGPropValFormatFlags fmtFlags = property->HasFlag(wxPGPropertyFlags::ReadOnly) ? + wxPGPropValFormatFlags::Null : wxPGPropValFormatFlags::EditableValue; +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + wxString correctText = property->GetValueAsStringWithCheck(fmtFlags); +#else + wxString correctText = property->GetValueAsString(fmtFlags); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 if ( tc->GetValue() != correctText ) { @@ -726,7 +751,12 @@ void wxPropertyGrid::OnComboItemPaint( const wxPGComboBox* pCb, else { if ( !p->IsValueUnspecified() ) - text = p->GetValueAsString(0); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + text = p->GetValueAsStringWithCheck(wxPGPropValFormatFlags::Null); +#else + text = p->GetValueAsString(wxPGPropValFormatFlags::Null); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 } } @@ -948,11 +978,16 @@ wxWindow* wxPGChoiceEditor::CreateControlsBase( wxPropertyGrid* propGrid, wxString defString; int index = property->GetChoiceSelection(); - int argFlags = 0; + wxPGPropValFormatFlags fmtFlags = wxPGPropValFormatFlags::Null; if ( !property->HasFlag(wxPGPropertyFlags::ReadOnly) && !property->IsValueUnspecified() ) - argFlags |= wxPG_EDITABLE_VALUE; - defString = property->GetValueAsString(argFlags); + fmtFlags |= wxPGPropValFormatFlags::EditableValue; +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + defString = property->GetValueAsStringWithCheck(fmtFlags); +#else + defString = property->GetValueAsString(fmtFlags); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 wxArrayString labels = choices.GetLabels(); @@ -1135,7 +1170,12 @@ bool wxPGChoiceEditor::GetValueFromControl( wxVariant& variant, wxPGProperty* pr property->IsValueUnspecified() ) { - return property->IntToValue(variant, index, wxPG_PROPERTY_SPECIFIC); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + return property->IntToValueWithCheck(variant, index, wxPGPropValFormatFlags::PropertySpecific); +#else + return property->IntToValue(variant, index, wxPGPropValFormatFlags::PropertySpecific); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 } return false; } @@ -1199,7 +1239,12 @@ void wxPGComboBoxEditor::UpdateControl( wxPGProperty* property, wxWindow* ctrl ) { wxOwnerDrawnComboBox* cb = (wxOwnerDrawnComboBox*)ctrl; const int index = property->GetChoiceSelection(); - wxString s = property->GetValueAsString(wxPG_EDITABLE_VALUE); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + wxString s = property->GetValueAsStringWithCheck(wxPGPropValFormatFlags::EditableValue); +#else + wxString s = property->GetValueAsString(wxPGPropValFormatFlags::EditableValue); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 cb->SetSelection(index); property->GetGrid()->SetupTextCtrlValue(s); cb->SetValue(s); @@ -1247,7 +1292,12 @@ bool wxPGComboBoxEditor::GetValueFromControl( wxVariant& variant, wxPGProperty* return true; } - bool res = property->StringToValue(variant, textVal, wxPG_EDITABLE_VALUE|wxPG_PROPERTY_SPECIFIC); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + bool res = property->StringToValueWithCheck(variant, textVal, wxPGPropValFormatFlags::EditableValue|wxPGPropValFormatFlags::PropertySpecific); +#else + bool res = property->StringToValue(variant, textVal, wxPGPropValFormatFlags::EditableValue | wxPGPropValFormatFlags::PropertySpecific); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 // Changing unspecified always causes event (returning // true here should be enough to trigger it). @@ -1724,7 +1774,12 @@ bool wxPGCheckBoxEditor::GetValueFromControl( wxVariant& variant, wxPGProperty* property->IsValueUnspecified() ) { - return property->IntToValue(variant, index, wxPG_PROPERTY_SPECIFIC); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + return property->IntToValueWithCheck(variant, index, wxPGPropValFormatFlags::PropertySpecific); +#else + return property->IntToValue(variant, index, wxPGPropValFormatFlags::PropertySpecific); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 } return false; } @@ -2048,7 +2103,12 @@ wxWindow* wxPropertyGrid::GenerateEditorTextCtrlAndButton( const wxPoint& pos, wxString text; if ( !property->IsValueUnspecified() ) - text = property->GetValueAsString(property->HasFlag(wxPGPropertyFlags::ReadOnly)?0:wxPG_EDITABLE_VALUE); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + text = property->GetValueAsStringWithCheck(property->HasFlag(wxPGPropertyFlags::ReadOnly)?wxPGPropValFormatFlags::Null : wxPGPropValFormatFlags::EditableValue); +#else + text = property->GetValueAsString(property->HasFlag(wxPGPropertyFlags::ReadOnly) ? wxPGPropValFormatFlags::Null : wxPGPropValFormatFlags::EditableValue); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 return GenerateEditorTextCtrl(pos, sz, text, but, 0, property->GetMaxLength()); } diff --git a/src/propgrid/property.cpp b/src/propgrid/property.cpp index a78d89d078..d955683d8f 100644 --- a/src/propgrid/property.cpp +++ b/src/propgrid/property.cpp @@ -273,7 +273,12 @@ bool wxPGDefaultRenderer::Render( wxDC& dc, const wxRect& rect, imageWidth = paintdata.m_drawnWidth; } +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + text = property->GetValueAsStringWithCheck(); +#else text = property->GetValueAsString(); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 // Add units string? if ( propertyGrid->GetColumnCount() <= 2 ) @@ -978,7 +983,7 @@ wxString wxPGProperty::GetColumnText( unsigned int col, int choiceIndex ) const */ void wxPGProperty::DoGenerateComposedValue( wxString& text, - int argFlags, + wxPGPropValFormatFlags flags, const wxVariantList* valueOverrides, wxPGHashMapS2S* childResults ) const { @@ -989,13 +994,13 @@ void wxPGProperty::DoGenerateComposedValue( wxString& text, return; if ( iMax > PWC_CHILD_SUMMARY_LIMIT && - !(argFlags & wxPG_FULL_VALUE) ) + !(flags & wxPGPropValFormatFlags::FullValue) ) iMax = PWC_CHILD_SUMMARY_LIMIT; size_t iMaxMinusOne = iMax-1; if ( !IsTextEditable() ) - argFlags |= wxPG_UNEDITABLE_COMPOSITE_FRAGMENT; + flags |= wxPGPropValFormatFlags::UneditableCompositeFragment; wxPGProperty* curChild = m_children[0]; @@ -1046,13 +1051,19 @@ void wxPGProperty::DoGenerateComposedValue( wxString& text, childValue.IsType(wxPG_VARIANT_TYPE_LIST) ) { wxVariantList& childList = childValue.GetList(); - DoGenerateComposedValue(s, argFlags|wxPG_COMPOSITE_FRAGMENT, + DoGenerateComposedValue(s, flags|wxPGPropValFormatFlags::CompositeFragment, &childList, childResults); } else { +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + s = curChild->ValueToStringWithCheck(childValue, + flags|wxPGPropValFormatFlags::CompositeFragment); +#else s = curChild->ValueToString(childValue, - argFlags|wxPG_COMPOSITE_FRAGMENT); + flags|wxPGPropValFormatFlags::CompositeFragment); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 } } @@ -1060,7 +1071,7 @@ void wxPGProperty::DoGenerateComposedValue( wxString& text, (*childResults)[curChild->GetName()] = s; bool skip = false; - if ( (argFlags & wxPG_UNEDITABLE_COMPOSITE_FRAGMENT) && s.empty() ) + if ( !!(flags & wxPGPropValFormatFlags::UneditableCompositeFragment) && s.empty() ) skip = true; if ( !curChild->HasAnyChild() || skip ) @@ -1071,8 +1082,8 @@ void wxPGProperty::DoGenerateComposedValue( wxString& text, if ( i < iMaxMinusOne ) { if ( text.length() > PWC_CHILD_SUMMARY_CHAR_LIMIT && - !(argFlags & wxPG_EDITABLE_VALUE) && - !(argFlags & wxPG_FULL_VALUE) ) + !(flags & wxPGPropValFormatFlags::EditableValue) && + !(flags & wxPGPropValFormatFlags::FullValue) ) break; if ( !skip ) @@ -1096,8 +1107,27 @@ void wxPGProperty::DoGenerateComposedValue( wxString& text, } } +#if WXWIN_COMPATIBILITY_3_2 +// By call to obsolete function we want to check if user-overriden function is still in use +wxString wxPGProperty::ValueToStringWithCheck(wxVariant& variant, wxPGPropValFormatFlags flags) const +{ + m_oldValueToStringCalled = false; + wxString res = ValueToString(variant, static_cast(flags)); + if ( m_oldValueToStringCalled ) + { + // Our own function was called - this implies that call was forwarded to the new overriding + // function and there is no need to call it explicitly. + } + else + { // User-overriden obsolete function was called + wxFAIL_MSG(wxString::Format("in %s use ValueToString with 'flags' argument as wxPGPropValFormatFlags", GetClassInfo()->GetClassName())); + } + return res; +} +#endif // WXWIN_COMPATIBILITY_3_2 + wxString wxPGProperty::ValueToString( wxVariant& WXUNUSED(value), - int argFlags ) const + wxPGPropValFormatFlags flags ) const { wxCHECK_MSG( HasAnyChild(), wxString(), @@ -1105,39 +1135,63 @@ wxString wxPGProperty::ValueToString( wxVariant& WXUNUSED(value), wxS("override GetValueAsString") ); // FIXME: Currently code below only works if value is actually m_value - wxASSERT_MSG( argFlags & wxPG_VALUE_IS_CURRENT, + wxASSERT_MSG( !!(flags & wxPGPropValFormatFlags::ValueIsCurrent), wxS("Sorry, currently default wxPGProperty::ValueToString() ") wxS("implementation only works if value is m_value.") ); wxString text; - DoGenerateComposedValue(text, argFlags); + DoGenerateComposedValue(text, flags); return text; } -wxString wxPGProperty::GetValueAsString( int argFlags ) const +#if WXWIN_COMPATIBILITY_3_2 +// By call to obsolete function we want to check if user-overriden function is still in use +wxString wxPGProperty::GetValueAsStringWithCheck(wxPGPropValFormatFlags flags) const +{ + m_oldGetValueAsString = false; + wxString res = GetValueAsString(static_cast(flags)); + if ( m_oldGetValueAsString ) + { + // Our own function was called - this implies that call was forwarded to the new overriding + // function and there is no need to call it explicitly. + } + else + { // User-overriden obsolete function was called + wxFAIL_MSG(wxString::Format("in %s use GetValueAsString with 'flags' argument as wxPGPropValFormatFlags", GetClassInfo()->GetClassName())); + } + return res; +} +#endif // WXWIN_COMPATIBILITY_3_2 + +wxString wxPGProperty::GetValueAsString(wxPGPropValFormatFlags flags) const { wxPropertyGrid* pg = GetGrid(); wxCHECK_MSG( pg, wxString(), wxS("Cannot get valid value for detached property") ); if ( IsValueUnspecified() ) - return pg->GetUnspecifiedValueText(argFlags); + return pg->GetUnspecifiedValueText(flags); if ( m_commonValue == -1 ) { wxVariant value(GetValue()); - return ValueToString(value, argFlags|wxPG_VALUE_IS_CURRENT); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + return ValueToStringWithCheck(value, flags|wxPGPropValFormatFlags::ValueIsCurrent); +#else + return ValueToString(value, flags|wxPGPropValFormatFlags::ValueIsCurrent); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 } // // Return common value's string representation const wxPGCommonValue* cv = pg->GetCommonValue(m_commonValue); - if ( argFlags & wxPG_FULL_VALUE ) + if ( !!(flags & wxPGPropValFormatFlags::FullValue) ) { return cv->GetLabel(); } - else if ( argFlags & wxPG_EDITABLE_VALUE ) + else if ( !!(flags & wxPGPropValFormatFlags::EditableValue) ) { return cv->GetEditableText(); } @@ -1147,14 +1201,52 @@ wxString wxPGProperty::GetValueAsString( int argFlags ) const } } -bool wxPGProperty::IntToValue( wxVariant& variant, int number, int WXUNUSED(argFlags) ) const +#if WXWIN_COMPATIBILITY_3_2 +// By call to obsolete function we want to check if user-overriden function is still in use +bool wxPGProperty::IntToValueWithCheck(wxVariant& variant, int number, wxPGPropValFormatFlags flags) const +{ + m_oldIntToValueCalled = false; + bool res = IntToValue(variant, number, static_cast(flags)); + if ( m_oldIntToValueCalled ) + { + // Our own function was called - this implies that call was forwarded to the new overriding + // function and there is no need to call it explicitly. + } + else + { // User-overriden obsolete function was called + wxFAIL_MSG(wxString::Format("in %s use IntoToValue with 'flags' argument as wxPGPropValFormatFlags", GetClassInfo()->GetClassName())); + } + return res; +} +#endif // WXWIN_COMPATIBILITY_3_2 + +bool wxPGProperty::IntToValue( wxVariant& variant, int number, wxPGPropValFormatFlags WXUNUSED(flags) ) const { variant = (long)number; return true; } +#if WXWIN_COMPATIBILITY_3_2 +// By call to obsolete function we want to check if user-overriden function is still in use#if WXWIN_COMPATIBILITY_3_2 +bool wxPGProperty::StringToValueWithCheck(wxVariant& variant, const wxString& text, wxPGPropValFormatFlags flags) const +{ + m_oldStringToValueCalled = false; + bool res = StringToValue(variant, text, static_cast(flags)); + if ( m_oldStringToValueCalled ) + { + // Our own function was called - this implies that call was forwarded to the new overriding + // function and there is no need to call it explicitly. + } + else + { // User-overriden obsolete function was called + wxFAIL_MSG(wxString::Format("in %s use StringToValue with 'flags' argument as wxPGPropValFormatFlags", GetClassInfo()->GetClassName())); + } + return res; +} +#endif // WXWIN_COMPATIBILITY_3_2 + // Convert semicolon delimited tokens into child values. -bool wxPGProperty::StringToValue( wxVariant& v, const wxString& text, int argFlags ) const +bool wxPGProperty::StringToValue( wxVariant& v, const wxString& text, wxPGPropValFormatFlags flags ) const { if ( !HasAnyChild() ) return false; @@ -1164,7 +1256,7 @@ bool wxPGProperty::StringToValue( wxVariant& v, const wxString& text, int argFla unsigned int iMax = m_children.size(); if ( iMax > PWC_CHILD_SUMMARY_LIMIT && - !(argFlags & wxPG_FULL_VALUE) ) + !(flags & wxPGPropValFormatFlags::FullValue) ) iMax = PWC_CHILD_SUMMARY_LIMIT; bool changed = false; @@ -1181,7 +1273,7 @@ bool wxPGProperty::StringToValue( wxVariant& v, const wxString& text, int argFla wxVariantList temp_list; wxVariant list(temp_list); - int propagatedFlags = argFlags & (wxPG_REPORT_ERROR|wxPG_PROGRAMMATIC_VALUE); + wxPGPropValFormatFlags propagatedFlags = flags & (wxPGPropValFormatFlags::ReportError|wxPGPropValFormatFlags::ProgrammaticValue); wxLogTrace("propgrid", wxS(">> %s.StringToValue('%s')"), GetLabel(), text); @@ -1216,14 +1308,20 @@ bool wxPGProperty::StringToValue( wxVariant& v, const wxString& text, int argFla token, childName); // Add only if editable or setting programmatically - if ( (argFlags & wxPG_PROGRAMMATIC_VALUE) || + if ( !!(flags & wxPGPropValFormatFlags::ProgrammaticValue) || (!child->HasFlag(wxPGPropertyFlags::Disabled) && !child->HasFlag(wxPGPropertyFlags::ReadOnly)) ) { if ( len > 0 ) { +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + if ( child->StringToValueWithCheck(variant, token, + propagatedFlags | wxPGPropValFormatFlags::CompositeFragment) ) +#else if ( child->StringToValue(variant, token, - propagatedFlags|wxPG_COMPOSITE_FRAGMENT) ) + propagatedFlags | wxPGPropValFormatFlags::CompositeFragment) ) +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 { // We really need to set the variant's name // *after* child->StringToValue() has been @@ -1295,14 +1393,20 @@ bool wxPGProperty::StringToValue( wxVariant& v, const wxString& text, int argFla wxVariant oldChildValue = child->GetValue(); wxVariant variant(oldChildValue); - if ( (argFlags & wxPG_PROGRAMMATIC_VALUE) || + if ( !!(flags & wxPGPropValFormatFlags::ProgrammaticValue) || (!child->HasFlag(wxPGPropertyFlags::Disabled) && !child->HasFlag(wxPGPropertyFlags::ReadOnly)) ) { wxString childName = child->GetBaseName(); - bool stvRes = child->StringToValue( variant, token, - propagatedFlags ); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + bool stvRes = child->StringToValueWithCheck(variant, token, + propagatedFlags); +#else + bool stvRes = child->StringToValue(variant, token, + propagatedFlags); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 if ( stvRes || (variant != oldChildValue) ) { variant.SetName(childName); @@ -1350,19 +1454,19 @@ bool wxPGProperty::StringToValue( wxVariant& v, const wxString& text, int argFla return changed; } -bool wxPGProperty::SetValueFromString( const wxString& text, int argFlags ) +bool wxPGProperty::SetValueFromString( const wxString& text, wxPGPropValFormatFlags flags ) { wxVariant variant(m_value); - bool res = StringToValue(variant, text, argFlags); + bool res = StringToValue(variant, text, flags); if ( res ) SetValue(variant); return res; } -bool wxPGProperty::SetValueFromInt( long number, int argFlags ) +bool wxPGProperty::SetValueFromInt( long number, wxPGPropValFormatFlags flags ) { wxVariant variant(m_value); - bool res = IntToValue(variant, number, argFlags); + bool res = IntToValue(variant, number, flags); if ( res ) SetValue(variant); return res; @@ -2901,15 +3005,15 @@ wxPropertyCategory::wxPropertyCategory( const wxString &label, const wxString& n } wxString wxPropertyCategory::ValueToString( wxVariant& WXUNUSED(value), - int WXUNUSED(argFlags) ) const + wxPGPropValFormatFlags WXUNUSED(flags) ) const { return m_value.IsType(wxPG_VARIANT_TYPE_STRING) ? m_value.GetString() : wxString(); } -wxString wxPropertyCategory::GetValueAsString( int argFlags ) const +wxString wxPropertyCategory::GetValueAsString(wxPGPropValFormatFlags flags) const { // Unspecified value is always empty string - return IsValueUnspecified() ? wxString() : wxPGProperty::GetValueAsString(argFlags); + return IsValueUnspecified() ? wxString() : wxPGProperty::GetValueAsString(flags); } static int DoGetTextExtent(const wxWindow* wnd, const wxString& label, const wxFont& font) diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 3ea759876c..202ee21929 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -3485,7 +3485,12 @@ wxVariant wxPropertyGrid::GetUncommittedPropertyValue() if ( !tc || !IsEditorsValueModified() ) return value; +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + if ( !prop->StringToValueWithCheck(value, tc->GetValue()) ) +#else if ( !prop->StringToValue(value, tc->GetValue()) ) +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 return value; if ( !PerformValidation(prop, value, IsStandaloneValidation) ) @@ -3865,13 +3870,13 @@ void wxPropertyGrid::CustomSetCursor( int type, bool override ) // ----------------------------------------------------------------------- wxString -wxPropertyGrid::GetUnspecifiedValueText( int argFlags ) const +wxPropertyGrid::GetUnspecifiedValueText(wxPGPropValFormatFlags flags) const { const wxPGCell& ua = GetUnspecifiedValueAppearance(); if ( ua.HasText() && - !(argFlags & wxPG_FULL_VALUE) && - !(argFlags & wxPG_EDITABLE_VALUE) ) + !(flags & wxPGPropValFormatFlags::FullValue) && + !(flags & wxPGPropValFormatFlags::EditableValue) ) return ua.GetText(); return wxString(); @@ -5098,7 +5103,12 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxSize imageSize = GetImageSize(m_propHover, -1); if ( imageSize.x > 0 ) imageWidth = imageSize.x; +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + tipString = m_propHover->GetValueAsStringWithCheck(); +#else tipString = m_propHover->GetValueAsString(); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 if ( GetColumnCount() <= 2 ) { wxString unitsString = m_propHover->GetAttribute(wxPG_ATTR_UNITS, wxString()); @@ -6396,8 +6406,8 @@ wxPGProperty* wxPropertyGridPopulator::Add( const wxString& propClass, m_state->DoInsert(parent, -1, property); if ( propValue ) - property->SetValueFromString( *propValue, wxPG_FULL_VALUE| - wxPG_PROGRAMMATIC_VALUE ); + property->SetValueFromString( *propValue, wxPGPropValFormatFlags::FullValue| + wxPGPropValFormatFlags::ProgrammaticValue ); return property; } diff --git a/src/propgrid/propgridiface.cpp b/src/propgrid/propgridiface.cpp index fe95145514..d3b3d71714 100644 --- a/src/propgrid/propgridiface.cpp +++ b/src/propgrid/propgridiface.cpp @@ -424,16 +424,16 @@ wxPGProperty* wxPropertyGridInterface::GetPropertyByLabel( const wxString& label // ---------------------------------------------------------------------------- void wxPropertyGridInterface::DoSetPropertyAttribute( wxPGPropArg id, const wxString& name, - wxVariant& value, wxPGPropertyValuesFlags argFlags ) + wxVariant& value, wxPGPropertyValuesFlags flags ) { wxPG_PROP_ARG_CALL_PROLOG() p->SetAttribute( name, value ); // property is also refreshed here - if ( !!(argFlags & wxPGPropertyValuesFlags::Recurse) ) + if ( !!(flags & wxPGPropertyValuesFlags::Recurse) ) { for ( unsigned int i = 0; i < p->GetChildCount(); i++ ) - DoSetPropertyAttribute(p->Item(i), name, value, argFlags); + DoSetPropertyAttribute(p->Item(i), name, value, flags); } } @@ -748,7 +748,12 @@ wxVariant wxPropertyGridInterface::GetPropertyValue(wxPGPropArg id) wxString wxPropertyGridInterface::GetPropertyValueAsString( wxPGPropArg id ) const { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(wxString()) - return p->GetValueAsString(wxPG_FULL_VALUE); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + return p->GetValueAsStringWithCheck(wxPGPropValFormatFlags::FullValue); +#else + return p->GetValueAsString(wxPGPropValFormatFlags::FullValue); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 } bool wxPropertyGridInterface::GetPropertyValueAsBool( wxPGPropArg id ) const diff --git a/src/propgrid/propgridpagestate.cpp b/src/propgrid/propgridpagestate.cpp index c45c1b1e65..dfb5543371 100644 --- a/src/propgrid/propgridpagestate.cpp +++ b/src/propgrid/propgridpagestate.cpp @@ -1220,11 +1220,16 @@ bool wxPropertyGridPageState::DoSetPropertyValueString( wxPGProperty* p, const w { if ( p ) { - int flags = wxPG_REPORT_ERROR|wxPG_FULL_VALUE|wxPG_PROGRAMMATIC_VALUE; + constexpr wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::ReportError|wxPGPropValFormatFlags::FullValue|wxPGPropValFormatFlags::ProgrammaticValue; wxVariant variant = p->GetValueRef(); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + if ( p->StringToValueWithCheck(variant, value, flags) ) +#else if ( p->StringToValue(variant, value, flags) ) +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 { p->SetValue(variant); if ( p == m_pPropGrid->GetSelection() && IsDisplayed() ) diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index 259e4e9d6c..fb0951d5b6 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -70,23 +70,23 @@ void wxStringProperty::OnSetValue() } wxString wxStringProperty::ValueToString( wxVariant& value, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { wxString s = value.GetString(); if ( HasAnyChild() && HasFlag(wxPGPropertyFlags::ComposedValue) ) { // Value stored in m_value is non-editable, non-full value - if ( (argFlags & wxPG_FULL_VALUE) || - (argFlags & wxPG_EDITABLE_VALUE) || + if ( !!(flags & wxPGPropValFormatFlags::FullValue) || + !!(flags & wxPGPropValFormatFlags::EditableValue) || s.empty() ) { // Calling this under incorrect conditions will fail - wxASSERT_MSG( argFlags & wxPG_VALUE_IS_CURRENT, + wxASSERT_MSG( !!(flags & wxPGPropValFormatFlags::ValueIsCurrent), wxS("Sorry, currently default wxPGProperty::ValueToString() ") wxS("implementation only works if value is m_value.") ); - DoGenerateComposedValue(s, argFlags); + DoGenerateComposedValue(s, flags); } return s; @@ -94,16 +94,16 @@ wxString wxStringProperty::ValueToString( wxVariant& value, // If string is password and value is for visual purposes, // then return asterisks instead the actual string. - if ( !!(m_flags & wxPGPropertyFlags_Password) && !(argFlags & (wxPG_FULL_VALUE|wxPG_EDITABLE_VALUE)) ) + if ( !!(m_flags & wxPGPropertyFlags_Password) && !(flags & (wxPGPropValFormatFlags::FullValue|wxPGPropValFormatFlags::EditableValue)) ) return wxString(wxS('*'), s.length()); return s; } -bool wxStringProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const +bool wxStringProperty::StringToValue( wxVariant& variant, const wxString& text, wxPGPropValFormatFlags flags ) const { if ( HasAnyChild() && HasFlag(wxPGPropertyFlags::ComposedValue) ) - return wxPGProperty::StringToValue(variant, text, argFlags); + return wxPGProperty::StringToValue(variant, text, flags); if ( variant != text ) { @@ -251,7 +251,12 @@ namespace { { // Round value to the required precision. wxVariant variant = value; - wxString strVal = prop->ValueToString(variant, wxPG_FULL_VALUE); +#if WXWIN_COMPATIBILITY_3_2 + // Special implementation with check if user-overriden obsolete function is still in use + wxString strVal = prop->ValueToStringWithCheck(variant, wxPGPropValFormatFlags::FullValue); +#else + wxString strVal = prop->ValueToString(variant, wxPGPropValFormatFlags::FullValue); +#endif // WXWIN_COMPATIBILITY_3_2 | !WXWIN_COMPATIBILITY_3_2 wxNumberFormatter::FromString(strVal, &value); return value; } @@ -372,7 +377,7 @@ wxIntProperty::wxIntProperty( const wxString& label, const wxString& name, #endif wxString wxIntProperty::ValueToString( wxVariant& value, - int WXUNUSED(argFlags) ) const + wxPGPropValFormatFlags WXUNUSED(flags) ) const { const wxString valType(value.GetType()); if ( valType == wxPG_VARIANT_TYPE_LONG ) @@ -390,7 +395,7 @@ wxString wxIntProperty::ValueToString( wxVariant& value, return wxString(); } -bool wxIntProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const +bool wxIntProperty::StringToValue( wxVariant& variant, const wxString& text, wxPGPropValFormatFlags flags ) const { if ( text.empty() ) { @@ -445,13 +450,13 @@ bool wxIntProperty::StringToValue( wxVariant& variant, const wxString& text, int } } } - else if ( argFlags & wxPG_REPORT_ERROR ) + else if ( !!(flags & wxPGPropValFormatFlags::ReportError) ) { } return false; } -bool wxIntProperty::IntToValue( wxVariant& variant, int value, int WXUNUSED(argFlags) ) const +bool wxIntProperty::IntToValue( wxVariant& variant, int value, wxPGPropValFormatFlags WXUNUSED(flags) ) const { if ( !variant.IsType(wxPG_VARIANT_TYPE_LONG) || variant != (long)value ) { @@ -586,7 +591,7 @@ wxUIntProperty::wxUIntProperty( const wxString& label, const wxString& name, } #endif -wxString wxUIntProperty::ValueToString(wxVariant& value, int argFlags) const +wxString wxUIntProperty::ValueToString(wxVariant& value, wxPGPropValFormatFlags flags) const { static const wxStringCharType* const gs_uintTemplates32[wxPG_UINT_TEMPLATE_MAX] = { @@ -639,7 +644,7 @@ wxString wxUIntProperty::ValueToString(wxVariant& value, int argFlags) const const wxString valType(value.GetType()); if ( valType == wxPG_VARIANT_TYPE_LONG ) { - const wxStringCharType* fmt = argFlags & wxPG_EDITABLE_VALUE ? + const wxStringCharType* fmt = !!(flags & wxPGPropValFormatFlags::EditableValue) ? gs_uintEditTemplates32[index] : gs_uintTemplates32[index]; return wxString::Format(fmt, (unsigned long)value.GetLong()); @@ -647,7 +652,7 @@ wxString wxUIntProperty::ValueToString(wxVariant& value, int argFlags) const #if wxUSE_LONGLONG else if ( valType == wxPG_VARIANT_TYPE_ULONGLONG ) { - const wxStringCharType* fmt = argFlags & wxPG_EDITABLE_VALUE ? + const wxStringCharType* fmt = !!(flags & wxPGPropValFormatFlags::EditableValue) ? gs_uintEditTemplates64[index] : gs_uintTemplates64[index]; wxULongLong ull = value.GetULongLong(); @@ -657,7 +662,7 @@ wxString wxUIntProperty::ValueToString(wxVariant& value, int argFlags) const return wxString(); } -bool wxUIntProperty::StringToValue(wxVariant& variant, const wxString& text, int argFlags) const +bool wxUIntProperty::StringToValue(wxVariant& variant, const wxString& text, wxPGPropValFormatFlags flags) const { if ( text.empty() ) { @@ -707,14 +712,14 @@ bool wxUIntProperty::StringToValue(wxVariant& variant, const wxString& text, int return true; } } - else if ( argFlags & wxPG_REPORT_ERROR ) + else if ( !!(flags & wxPGPropValFormatFlags::ReportError) ) { } return false; } -bool wxUIntProperty::IntToValue( wxVariant& variant, int number, int WXUNUSED(argFlags) ) const +bool wxUIntProperty::IntToValue( wxVariant& variant, int number, wxPGPropValFormatFlags WXUNUSED(flags) ) const { if ( variant != (long)number ) { @@ -920,19 +925,19 @@ const wxString& wxPropertyGrid::DoubleToString(wxString& target, #endif // WXWIN_COMPATIBILITY_3_0 wxString wxFloatProperty::ValueToString( wxVariant& value, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { wxString text; if ( !value.IsNull() ) { text = wxNumberFormatter::ToString(value.GetDouble(), m_precision, - argFlags & wxPG_FULL_VALUE ? wxNumberFormatter::Style_None - : wxNumberFormatter::Style_NoTrailingZeroes); + !!(flags & wxPGPropValFormatFlags::FullValue) ? wxNumberFormatter::Style_None + : wxNumberFormatter::Style_NoTrailingZeroes); } return text; } -bool wxFloatProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const +bool wxFloatProperty::StringToValue( wxVariant& variant, const wxString& text, wxPGPropValFormatFlags flags ) const { if ( text.empty() ) { @@ -950,7 +955,7 @@ bool wxFloatProperty::StringToValue( wxVariant& variant, const wxString& text, i return true; } } - else if ( argFlags & wxPG_REPORT_ERROR ) + else if ( !!(flags & wxPGPropValFormatFlags::ReportError) ) { } return false; @@ -1050,13 +1055,13 @@ wxBoolProperty::wxBoolProperty( const wxString& label, const wxString& name, boo } wxString wxBoolProperty::ValueToString( wxVariant& value, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { bool boolValue = value.GetBool(); // As a fragment of composite string value, // make it a little more readable. - if ( argFlags & wxPG_COMPOSITE_FRAGMENT ) + if ( !!(flags & wxPGPropValFormatFlags::CompositeFragment) ) { if ( boolValue ) { @@ -1064,7 +1069,7 @@ wxString wxBoolProperty::ValueToString( wxVariant& value, } else { - if ( argFlags & wxPG_UNEDITABLE_COMPOSITE_FRAGMENT ) + if ( !!(flags & wxPGPropValFormatFlags::UneditableCompositeFragment) ) return wxString(); wxString notFmt; @@ -1077,7 +1082,7 @@ wxString wxBoolProperty::ValueToString( wxVariant& value, } } - if ( !(argFlags & wxPG_FULL_VALUE) ) + if ( !(flags & wxPGPropValFormatFlags::FullValue) ) { return wxPGGlobalVars->m_boolChoices[boolValue?1:0].GetText(); } @@ -1085,7 +1090,7 @@ wxString wxBoolProperty::ValueToString( wxVariant& value, return boolValue? wxS("true"): wxS("false"); } -bool wxBoolProperty::StringToValue( wxVariant& variant, const wxString& text, int WXUNUSED(argFlags) ) const +bool wxBoolProperty::StringToValue( wxVariant& variant, const wxString& text, wxPGPropValFormatFlags WXUNUSED(flags) ) const { bool boolValue = false; if ( text.CmpNoCase(wxPGGlobalVars->m_boolChoices[1].GetText()) == 0 || @@ -1107,7 +1112,7 @@ bool wxBoolProperty::StringToValue( wxVariant& variant, const wxString& text, in return false; } -bool wxBoolProperty::IntToValue( wxVariant& variant, int value, int ) const +bool wxBoolProperty::IntToValue( wxVariant& variant, int value, wxPGPropValFormatFlags ) const { bool boolValue = (bool)value; @@ -1229,11 +1234,11 @@ void wxEnumProperty::OnSetValue() int index = -1; if ( valType == wxPG_VARIANT_TYPE_LONG ) { - ValueFromInt_(m_value, &index, m_value.GetLong(), wxPG_FULL_VALUE); + ValueFromInt_(m_value, &index, m_value.GetLong(), wxPGPropValFormatFlags::FullValue); } else if ( valType == wxPG_VARIANT_TYPE_STRING ) { - ValueFromString_(m_value, &index, m_value.GetString(), 0); + ValueFromString_(m_value, &index, m_value.GetString(), wxPGPropValFormatFlags::Null); } else { @@ -1250,13 +1255,13 @@ bool wxEnumProperty::ValidateValue( wxVariant& value, wxPGValidationInfo& WXUNUS // unless property has string as preferred value type // To reduce code size, use conversion here as well if ( value.IsType(wxPG_VARIANT_TYPE_STRING) ) - return ValueFromString_(value, nullptr, value.GetString(), wxPG_PROPERTY_SPECIFIC); + return ValueFromString_(value, nullptr, value.GetString(), wxPGPropValFormatFlags::PropertySpecific); return true; } wxString wxEnumProperty::ValueToString( wxVariant& value, - int WXUNUSED(argFlags) ) const + wxPGPropValFormatFlags WXUNUSED(flags) ) const { if ( value.IsType(wxPG_VARIANT_TYPE_STRING) ) return value.GetString(); @@ -1268,17 +1273,17 @@ wxString wxEnumProperty::ValueToString( wxVariant& value, return m_choices.GetLabel(index); } -bool wxEnumProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const +bool wxEnumProperty::StringToValue( wxVariant& variant, const wxString& text, wxPGPropValFormatFlags flags ) const { - return ValueFromString_(variant, nullptr, text, argFlags); + return ValueFromString_(variant, nullptr, text, flags); } -bool wxEnumProperty::IntToValue( wxVariant& variant, int intVal, int argFlags ) const +bool wxEnumProperty::IntToValue( wxVariant& variant, int intVal, wxPGPropValFormatFlags flags ) const { - return ValueFromInt_(variant, nullptr, intVal, argFlags); + return ValueFromInt_(variant, nullptr, intVal, flags); } -bool wxEnumProperty::ValueFromString_(wxVariant& value, int* pIndex, const wxString& text, int WXUNUSED(argFlags)) const +bool wxEnumProperty::ValueFromString_(wxVariant& value, int* pIndex, const wxString& text, wxPGPropValFormatFlags WXUNUSED(flags)) const { int useIndex = -1; long useValue = 0; @@ -1313,13 +1318,13 @@ bool wxEnumProperty::ValueFromString_(wxVariant& value, int* pIndex, const wxStr return false; } -bool wxEnumProperty::ValueFromInt_(wxVariant& value, int* pIndex, int intVal, int argFlags) const +bool wxEnumProperty::ValueFromInt_(wxVariant& value, int* pIndex, int intVal, wxPGPropValFormatFlags flags) const { - // If wxPG_FULL_VALUE is *not* in argFlags, then intVal is index from combo box. + // If wxPGPropValFormatFlags::FullValue is *not* in flags, then intVal is index from combo box. // int setAsNextIndex = -2; - if ( argFlags & wxPG_FULL_VALUE ) + if ( !!(flags & wxPGPropValFormatFlags::FullValue) ) { setAsNextIndex = GetIndexForValue( intVal ); } @@ -1333,7 +1338,7 @@ bool wxEnumProperty::ValueFromInt_(wxVariant& value, int* pIndex, int intVal, in if ( setAsNextIndex != -2 ) { - if ( !(argFlags & wxPG_FULL_VALUE) ) + if ( !(flags & wxPGPropValFormatFlags::FullValue) ) intVal = m_choices.GetValue(intVal); value = (long)intVal; @@ -1406,12 +1411,12 @@ void wxEditEnumProperty::OnSetValue() int index = -1; if ( valType == wxPG_VARIANT_TYPE_LONG ) { - ValueFromInt_(m_value, &index, m_value.GetLong(), wxPG_FULL_VALUE); + ValueFromInt_(m_value, &index, m_value.GetLong(), wxPGPropValFormatFlags::FullValue); } else if ( valType == wxPG_VARIANT_TYPE_STRING ) { wxString val = m_value.GetString(); - ValueFromString_(m_value, &index, val, 0); + ValueFromString_(m_value, &index, val, wxPGPropValFormatFlags::Null); // If text is not any of the choices, store as plain text instead. if (index == -1) { @@ -1428,10 +1433,10 @@ void wxEditEnumProperty::OnSetValue() } bool wxEditEnumProperty::StringToValue(wxVariant& variant, - const wxString& text, int argFlags) const + const wxString& text, wxPGPropValFormatFlags flags) const { int index; - bool res = ValueFromString_(variant, &index, text, argFlags); + bool res = ValueFromString_(variant, &index, text, flags); // If text is not any of the choices, store as plain text instead. if (index == -1) { @@ -1588,7 +1593,7 @@ void wxFlagsProperty::OnSetValue() } wxString wxFlagsProperty::ValueToString( wxVariant& value, - int WXUNUSED(argFlags) ) const + wxPGPropValFormatFlags WXUNUSED(flags) ) const { wxString text; @@ -1616,7 +1621,7 @@ wxString wxFlagsProperty::ValueToString( wxVariant& value, } // Translate string into flag tokens -bool wxFlagsProperty::StringToValue( wxVariant& variant, const wxString& text, int ) const +bool wxFlagsProperty::StringToValue( wxVariant& variant, const wxString& text, wxPGPropValFormatFlags ) const { if ( !m_choices.IsOk() ) return false; @@ -1741,12 +1746,12 @@ wxDirProperty::wxDirProperty( const wxString& label, const wxString& name, const SetValue(value); } -wxString wxDirProperty::ValueToString(wxVariant& value, int WXUNUSED(argFlags)) const +wxString wxDirProperty::ValueToString(wxVariant& value, wxPGPropValFormatFlags WXUNUSED(flags)) const { return value; } -bool wxDirProperty::StringToValue(wxVariant& variant, const wxString& text, int) const +bool wxDirProperty::StringToValue(wxVariant& variant, const wxString& text, wxPGPropValFormatFlags) const { if ( variant != text ) { @@ -1959,7 +1964,7 @@ wxFileName wxFileProperty::GetFileName() const } wxString wxFileProperty::ValueToString( wxVariant& value, - int argFlags ) const + wxPGPropValFormatFlags flags ) const { wxFileName filename = value.GetString(); @@ -1970,7 +1975,7 @@ wxString wxFileProperty::ValueToString( wxVariant& value, if ( fullName.empty() ) return wxString(); - if ( argFlags & wxPG_FULL_VALUE ) + if ( !!(flags & wxPGPropValFormatFlags::FullValue) ) { return filename.GetFullPath(); } @@ -1988,11 +1993,11 @@ wxString wxFileProperty::ValueToString( wxVariant& value, return filename.GetFullName(); } -bool wxFileProperty::StringToValue( wxVariant& variant, const wxString& text, int argFlags ) const +bool wxFileProperty::StringToValue( wxVariant& variant, const wxString& text, wxPGPropValFormatFlags flags ) const { wxFileName filename = variant.GetString(); - if ( !!(m_flags & wxPGPropertyFlags::ShowFullFileName) || (argFlags & wxPG_FULL_VALUE) ) + if ( !!(m_flags & wxPGPropertyFlags::ShowFullFileName) || !!(flags & wxPGPropValFormatFlags::FullValue) ) { if ( filename != text ) { @@ -2101,7 +2106,7 @@ wxLongStringProperty::wxLongStringProperty( const wxString& label, const wxStrin } wxString wxLongStringProperty::ValueToString( wxVariant& value, - int WXUNUSED(argFlags) ) const + wxPGPropValFormatFlags WXUNUSED(flags) ) const { return value; } @@ -2164,7 +2169,7 @@ bool wxLongStringProperty::DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& va return false; } -bool wxLongStringProperty::StringToValue( wxVariant& variant, const wxString& text, int ) const +bool wxLongStringProperty::StringToValue( wxVariant& variant, const wxString& text, wxPGPropValFormatFlags ) const { if ( variant != text ) { @@ -2570,11 +2575,11 @@ wxString wxArrayStringProperty::ConvertArrayToString(const wxArrayString& arr, } wxString wxArrayStringProperty::ValueToString( wxVariant& WXUNUSED(value), - int argFlags ) const + wxPGPropValFormatFlags flags ) const { // // If this is called from GetValueAsString(), return cached string - if ( argFlags & wxPG_VALUE_IS_CURRENT ) + if ( !!(flags & wxPGPropValFormatFlags::ValueIsCurrent) ) { return m_display; } @@ -2723,7 +2728,7 @@ bool wxArrayStringProperty::DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& v } bool wxArrayStringProperty::StringToValue( wxVariant& variant, - const wxString& text, int ) const + const wxString& text, wxPGPropValFormatFlags ) const { wxArrayString arr; From e7ab6a6d5370fe9e2bcef1a6abd76694a8c2bc72 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 17:51:14 +0100 Subject: [PATCH 222/257] Use enum class to represent wxPGNumericValidationConstants This is for better type safety. --- include/wx/propgrid/props.h | 36 ++++++++++++++++++--------- interface/wx/propgrid/props.h | 8 +++--- src/propgrid/props.cpp | 46 +++++++++++++++++++++-------------- 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/include/wx/propgrid/props.h b/include/wx/propgrid/props.h index 29d4b6a0e6..dd4b2a86c8 100644 --- a/include/wx/propgrid/props.h +++ b/include/wx/propgrid/props.h @@ -133,18 +133,27 @@ protected: // ----------------------------------------------------------------------- // Constants used with NumericValidation<>(). -enum wxPGNumericValidationConstants +enum class wxPGNumericValidationMode { // Instead of modifying the value, show an error message. - wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE = 0, + ErrorMessage, // Modify value, but stick with the limitations. - wxPG_PROPERTY_VALIDATION_SATURATE = 1, + Saturate, // Modify value, wrap around on overflow. - wxPG_PROPERTY_VALIDATION_WRAP = 2 + Wrap }; +#if WXWIN_COMPATIBILITY_3_2 +wxDEPRECATED_MSG("use wxPGNumericValidationMode::ErrorMessage instead") +constexpr wxPGNumericValidationMode wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE { wxPGNumericValidationMode::ErrorMessage }; +wxDEPRECATED_MSG("use wxPGNumericValidationMode::Saturate instead") +constexpr wxPGNumericValidationMode wxPG_PROPERTY_VALIDATION_SATURATE { wxPGNumericValidationMode::Saturate }; +wxDEPRECATED_MSG("use wxPGNumericValidationMode::Wrap instead") +constexpr wxPGNumericValidationMode wxPG_PROPERTY_VALIDATION_WRAP { wxPGNumericValidationMode::Wrap }; +#endif // WXWIN_COMPATIBILITY_3_2 + // ----------------------------------------------------------------------- #if wxUSE_VALIDATORS @@ -182,9 +191,16 @@ public: bool UseSpinMotion() const { return m_spinMotion; } // Common validation code - for internal use. +#if WXWIN_COMPATIBILITY_3_2 template + wxDEPRECATED_MSG("use DoNumericValidation with 'mode' argument as wxPGNumericValidationMode") bool DoNumericValidation(T& value, wxPGValidationInfo* pValidationInfo, int mode, T defMin, T defMax) const; +#endif // WXWIN_COMPATIBILITY_3_2 + + template + bool DoNumericValidation(T& value, wxPGValidationInfo* pValidationInfo, + wxPGNumericValidationMode mode, T defMin, T defMax) const; protected: wxNumericProperty(const wxString& label, const wxString& name); @@ -255,14 +271,12 @@ private: static bool DoValidation( const wxNumericProperty* property, wxLongLong& value, wxPGValidationInfo* pValidationInfo, - int mode = - wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ); + wxPGNumericValidationMode = wxPGNumericValidationMode::ErrorMessage); #endif // wxUSE_LONGLONG static bool DoValidation(const wxNumericProperty* property, long& value, wxPGValidationInfo* pValidationInfo, - int mode = - wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); + wxPGNumericValidationMode mode = wxPGNumericValidationMode::ErrorMessage); }; // ----------------------------------------------------------------------- @@ -332,12 +346,12 @@ private: static bool DoValidation(const wxNumericProperty* property, wxULongLong& value, wxPGValidationInfo* pValidationInfo, - int mode =wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); + wxPGNumericValidationMode = wxPGNumericValidationMode::ErrorMessage); #endif // wxUSE_LONGLONG static bool DoValidation(const wxNumericProperty* property, long& value, wxPGValidationInfo* pValidationInfo, - int mode = wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); + wxPGNumericValidationMode mode = wxPGNumericValidationMode::ErrorMessage); }; // ----------------------------------------------------------------------- @@ -390,7 +404,7 @@ private: static bool DoValidation(const wxNumericProperty* property, double& value, wxPGValidationInfo* pValidationInfo, - int mode = wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); + wxPGNumericValidationMode mode = wxPGNumericValidationMode::ErrorMessage); }; // ----------------------------------------------------------------------- diff --git a/interface/wx/propgrid/props.h b/interface/wx/propgrid/props.h index 34a8ff9426..bed6dc08a9 100644 --- a/interface/wx/propgrid/props.h +++ b/interface/wx/propgrid/props.h @@ -63,19 +63,19 @@ public: /** Constants used with NumericValidation<>(). */ -enum wxPGNumericValidationConstants +enum class wxPGNumericValidationMode { /** Instead of modifying the value, show an error message. */ - wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE = 0, + ErrorMessage, /** Modify value, but stick with the limitations. */ - wxPG_PROPERTY_VALIDATION_SATURATE = 1, + Saturate, /** Modify value, wrap around on overflow. */ - wxPG_PROPERTY_VALIDATION_WRAP = 2 + Wrap }; diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index fb0951d5b6..1b01d0e25a 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -265,9 +265,19 @@ namespace { // Common validation code to be called in ValidateValue() implementations. // Note that 'value' is reference on purpose, so we can write // back to it when mode is wxPG_PROPERTY_VALIDATION_SATURATE or wxPG_PROPERTY_VALIDATION_WRAP. +#if WXWIN_COMPATIBILITY_3_2 template bool wxNumericProperty::DoNumericValidation(T& value, wxPGValidationInfo* pValidationInfo, int mode, T defMin, T defMax) const +{ + return DoNumericValidation(value, pValidationInfo, + static_cast(mode), defMin, defMax); +} +#endif // WXWIN_COMPATIBILITY_3_2 + +template +bool wxNumericProperty::DoNumericValidation(T& value, wxPGValidationInfo* pValidationInfo, + wxPGNumericValidationMode mode, T defMin, T defMax) const { T min = defMin; T max = defMax; @@ -304,7 +314,7 @@ bool wxNumericProperty::DoNumericValidation(T& value, wxPGValidationInfo* pValid { if ( value < min ) { - if ( mode == wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ) + if ( mode == wxPGNumericValidationMode::ErrorMessage ) { wxString msg; wxVariant vmin = WXVARIANT(min); @@ -319,7 +329,7 @@ bool wxNumericProperty::DoNumericValidation(T& value, wxPGValidationInfo* pValid } pValidationInfo->SetFailureMessage(msg); } - else if ( mode == wxPG_PROPERTY_VALIDATION_SATURATE ) + else if ( mode == wxPGNumericValidationMode::Saturate ) value = min; else value = max - (min - value); @@ -331,7 +341,7 @@ bool wxNumericProperty::DoNumericValidation(T& value, wxPGValidationInfo* pValid { if ( value > max ) { - if ( mode == wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE ) + if ( mode == wxPGNumericValidationMode::ErrorMessage ) { wxString msg; wxVariant vmax = WXVARIANT(max); @@ -346,7 +356,7 @@ bool wxNumericProperty::DoNumericValidation(T& value, wxPGValidationInfo* pValid } pValidationInfo->SetFailureMessage(msg); } - else if ( mode == wxPG_PROPERTY_VALIDATION_SATURATE ) + else if ( mode == wxPGNumericValidationMode::Saturate ) value = max; else value = min + (value - max); @@ -470,7 +480,7 @@ bool wxIntProperty::IntToValue( wxVariant& variant, int value, wxPGPropValFormat bool wxIntProperty::DoValidation( const wxNumericProperty* property, wxLongLong& value, wxPGValidationInfo* pValidationInfo, - int mode ) + wxPGNumericValidationMode mode ) { return property->DoNumericValidation(value, pValidationInfo, @@ -481,7 +491,7 @@ bool wxIntProperty::DoValidation( const wxNumericProperty* property, bool wxIntProperty::DoValidation(const wxNumericProperty* property, long& value, wxPGValidationInfo* pValidationInfo, - int mode) + wxPGNumericValidationMode mode) { return property->DoNumericValidation(value, pValidationInfo, mode, wxPG_LONG_MIN, wxPG_LONG_MAX); @@ -496,7 +506,7 @@ bool wxIntProperty::ValidateValue( wxVariant& value, long ll = value.GetLong(); #endif return DoValidation(this, ll, &validationInfo, - wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); + wxPGNumericValidationMode::ErrorMessage); } wxValidator* wxIntProperty::GetClassValidator() @@ -520,8 +530,8 @@ wxValidator* wxIntProperty::DoGetValidator() const wxVariant wxIntProperty::AddSpinStepValue(long stepScale) const { - int mode = m_spinWrap ? wxPG_PROPERTY_VALIDATION_WRAP - : wxPG_PROPERTY_VALIDATION_SATURATE; + wxPGNumericValidationMode mode = m_spinWrap ? wxPGNumericValidationMode::Wrap + : wxPGNumericValidationMode::Saturate; wxVariant value = GetValue(); if ( value.GetType() == wxPG_VARIANT_TYPE_LONG ) { @@ -733,7 +743,7 @@ bool wxUIntProperty::IntToValue( wxVariant& variant, int number, wxPGPropValForm bool wxUIntProperty::DoValidation(const wxNumericProperty* property, wxULongLong& value, wxPGValidationInfo* pValidationInfo, - int mode ) + wxPGNumericValidationMode mode ) { return property->DoNumericValidation(value, pValidationInfo, mode, wxULongLong(0), wxULongLong(wxPG_ULLONG_MAX)); @@ -743,7 +753,7 @@ bool wxUIntProperty::DoValidation(const wxNumericProperty* property, bool wxUIntProperty::DoValidation(const wxNumericProperty* property, long& value, wxPGValidationInfo* pValidationInfo, - int mode) + wxPGNumericValidationMode mode) { return property->DoNumericValidation(value, pValidationInfo, mode, 0, wxPG_ULONG_MAX); @@ -757,7 +767,7 @@ bool wxUIntProperty::ValidateValue( wxVariant& value, wxPGValidationInfo& valida long uul = value.GetLong(); #endif return DoValidation(this, uul, &validationInfo, - wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); + wxPGNumericValidationMode::ErrorMessage); } wxValidator* wxUIntProperty::DoGetValidator() const @@ -806,8 +816,8 @@ bool wxUIntProperty::DoSetAttribute( const wxString& name, wxVariant& value ) wxVariant wxUIntProperty::AddSpinStepValue(long stepScale) const { - int mode = m_spinWrap ? wxPG_PROPERTY_VALIDATION_WRAP - : wxPG_PROPERTY_VALIDATION_SATURATE; + wxPGNumericValidationMode mode = m_spinWrap ? wxPGNumericValidationMode::Wrap + : wxPGNumericValidationMode::Saturate; wxVariant value = GetValue(); if ( value.GetType() == wxPG_VARIANT_TYPE_LONG ) { @@ -964,7 +974,7 @@ bool wxFloatProperty::StringToValue( wxVariant& variant, const wxString& text, w bool wxFloatProperty::DoValidation( const wxNumericProperty* property, double& value, wxPGValidationInfo* pValidationInfo, - int mode ) + wxPGNumericValidationMode mode ) { return property->DoNumericValidation(value, pValidationInfo, mode, wxPG_DBL_MIN, wxPG_DBL_MAX); @@ -976,7 +986,7 @@ wxFloatProperty::ValidateValue( wxVariant& value, { double fpv = value.GetDouble(); return DoValidation(this, fpv, &validationInfo, - wxPG_PROPERTY_VALIDATION_ERROR_MESSAGE); + wxPGNumericValidationMode::ErrorMessage); } bool wxFloatProperty::DoSetAttribute( const wxString& name, wxVariant& value ) @@ -1011,8 +1021,8 @@ wxValidator* wxFloatProperty::DoGetValidator() const wxVariant wxFloatProperty::AddSpinStepValue(long stepScale) const { - int mode = m_spinWrap ? wxPG_PROPERTY_VALIDATION_WRAP - : wxPG_PROPERTY_VALIDATION_SATURATE; + wxPGNumericValidationMode mode = m_spinWrap ? wxPGNumericValidationMode::Wrap + : wxPGNumericValidationMode::Saturate; wxVariant value = GetValue(); double v = value.GetDouble(); double step = m_spinStep.GetDouble(); From 3cb3d622120800a3c2b6d19360faef06eccce4da Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 17:53:35 +0100 Subject: [PATCH 223/257] Use enum class to represent NumericType This is for better type safety. --- include/wx/propgrid/props.h | 13 +++++++++++-- interface/wx/propgrid/props.h | 4 ++-- samples/propgrid/sampleprops.cpp | 2 +- src/propgrid/props.cpp | 10 +++++----- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/include/wx/propgrid/props.h b/include/wx/propgrid/props.h index dd4b2a86c8..59a5391dad 100644 --- a/include/wx/propgrid/props.h +++ b/include/wx/propgrid/props.h @@ -162,13 +162,22 @@ constexpr wxPGNumericValidationMode wxPG_PROPERTY_VALIDATION_WRAP { wxPGNumericV class WXDLLIMPEXP_PROPGRID wxNumericPropertyValidator : public wxTextValidator { public: - enum NumericType + enum class NumericType { - Signed = 0, + Signed, Unsigned, Float }; +#if WXWIN_COMPATIBILITY_3_2 + wxDEPRECATED_MSG("use NumericType::Signed instead") + static const NumericType Signed = NumericType::Signed; + wxDEPRECATED_MSG("use NumericType::Unsigned instead") + static const NumericType Unsigned = NumericType::Unsigned; + wxDEPRECATED_MSG("use NumericType::Float instead") + static const NumericType Float = NumericType::Float; +#endif // WXWIN_COMPATIBILITY_3_2 + wxNumericPropertyValidator( NumericType numericType, int base = 10 ); virtual ~wxNumericPropertyValidator() = default; virtual bool Validate(wxWindow* parent) override; diff --git a/interface/wx/propgrid/props.h b/interface/wx/propgrid/props.h index bed6dc08a9..16d9636b37 100644 --- a/interface/wx/propgrid/props.h +++ b/interface/wx/propgrid/props.h @@ -86,9 +86,9 @@ enum class wxPGNumericValidationMode class wxNumericPropertyValidator : public wxTextValidator { public: - enum NumericType + enum class NumericType { - Signed = 0, + Signed, Unsigned, Float }; diff --git a/samples/propgrid/sampleprops.cpp b/samples/propgrid/sampleprops.cpp index 442cd5e363..d22b46cf75 100644 --- a/samples/propgrid/sampleprops.cpp +++ b/samples/propgrid/sampleprops.cpp @@ -632,7 +632,7 @@ wxValidator* wxArrayDoubleProperty::DoGetValidator() const WX_PG_DOGETVALIDATOR_ENTRY() wxTextValidator* validator = - new wxNumericPropertyValidator(wxNumericPropertyValidator::Float); + new wxNumericPropertyValidator(wxNumericPropertyValidator::NumericType::Float); // Accept also a delimiter and space character validator->AddCharIncludes(m_delimiter); diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index 1b01d0e25a..fe6cb2c9b1 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -159,11 +159,11 @@ wxNumericPropertyValidator:: style |= wxFILTER_DIGITS; } - if ( numericType == Signed ) + if ( numericType == NumericType::Signed ) { allowedChars += wxS("-+"); } - else if ( numericType == Float ) + else if ( numericType == NumericType::Float ) { allowedChars += wxS("-+eE"); @@ -515,7 +515,7 @@ wxValidator* wxIntProperty::GetClassValidator() WX_PG_DOGETVALIDATOR_ENTRY() wxValidator* validator = new wxNumericPropertyValidator( - wxNumericPropertyValidator::Signed); + wxNumericPropertyValidator::NumericType::Signed); WX_PG_DOGETVALIDATOR_EXIT(validator) #else @@ -776,7 +776,7 @@ wxValidator* wxUIntProperty::DoGetValidator() const WX_PG_DOGETVALIDATOR_ENTRY() wxValidator* validator = new wxNumericPropertyValidator( - wxNumericPropertyValidator::Unsigned, + wxNumericPropertyValidator::NumericType::Unsigned, m_realBase); WX_PG_DOGETVALIDATOR_EXIT(validator) @@ -1006,7 +1006,7 @@ wxFloatProperty::GetClassValidator() WX_PG_DOGETVALIDATOR_ENTRY() wxValidator* validator = new wxNumericPropertyValidator( - wxNumericPropertyValidator::Float); + wxNumericPropertyValidator::NumericType::Float); WX_PG_DOGETVALIDATOR_EXIT(validator) #else From efa2870cb4391b0dedeaf3048744fa3952cf4ddd Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 17:55:11 +0100 Subject: [PATCH 224/257] Rename wxPGKeyboardActions type to wxPGKeyboardAction For regular enumeration singular name is more appropriate. --- include/wx/propgrid/propgrid.h | 63 ++++++++++++++------------- interface/wx/propgrid/propgrid.h | 8 ++-- samples/propgrid/propgrid.cpp | 2 +- src/propgrid/propgrid.cpp | 74 ++++++++++++++++---------------- 4 files changed, 75 insertions(+), 72 deletions(-) diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index 06b070675a..25387ea632 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -438,7 +438,7 @@ private: // These are used with wxPropertyGrid::AddActionTrigger() and // wxPropertyGrid::ClearActionTriggers(). -enum class wxPGKeyboardActions +enum class wxPGKeyboardAction { #if WXWIN_COMPATIBILITY_3_2 Invalid = 0, @@ -471,22 +471,25 @@ enum class wxPGKeyboardActions }; #if WXWIN_COMPATIBILITY_3_2 -wxDEPRECATED_MSG("use wxPGKeyboardActions::Invalid instead") -constexpr wxPGKeyboardActions wxPG_ACTION_INVALID { wxPGKeyboardActions::Invalid }; -wxDEPRECATED_MSG("use wxPGKeyboardActions::NextProperty instead") -constexpr wxPGKeyboardActions wxPG_ACTION_NEXT_PROPERTY { wxPGKeyboardActions::NextProperty }; -wxDEPRECATED_MSG("use wxPGKeyboardActions::PrevProperty instead") -constexpr wxPGKeyboardActions wxPG_ACTION_PREV_PROPERTY { wxPGKeyboardActions::PrevProperty }; -wxDEPRECATED_MSG("use wxPGKeyboardActions::ExpandProperty instead") -constexpr wxPGKeyboardActions wxPG_ACTION_EXPAND_PROPERTY { wxPGKeyboardActions::ExpandProperty }; -wxDEPRECATED_MSG("use wxPGKeyboardActions::CollapseProperty instead") -constexpr wxPGKeyboardActions wxPG_ACTION_COLLAPSE_PROPERTY { wxPGKeyboardActions::CollapseProperty }; -wxDEPRECATED_MSG("use wxPGKeyboardActions::CancelEdit instead") -constexpr wxPGKeyboardActions wxPG_ACTION_CANCEL_EDIT { wxPGKeyboardActions::CancelEdit }; -wxDEPRECATED_MSG("use wxPGKeyboardActions::Edit instead") -constexpr wxPGKeyboardActions wxPG_ACTION_EDIT { wxPGKeyboardActions::Edit }; -wxDEPRECATED_MSG("use wxPGKeyboardActions::PressButton instead") -constexpr wxPGKeyboardActions wxPG_ACTION_PRESS_BUTTON { wxPGKeyboardActions::PressButton }; +wxDEPRECATED_MSG("use wxPGKeyboardAction type instead") +typedef wxPGKeyboardAction wxPGKeyboardActions; + +wxDEPRECATED_MSG("use wxPGKeyboardAction::Invalid instead") +constexpr wxPGKeyboardAction wxPG_ACTION_INVALID { wxPGKeyboardAction::Invalid }; +wxDEPRECATED_MSG("use wxPGKeyboardAction::NextProperty instead") +constexpr wxPGKeyboardAction wxPG_ACTION_NEXT_PROPERTY { wxPGKeyboardAction::NextProperty }; +wxDEPRECATED_MSG("use wxPGKeyboardAction::PrevProperty instead") +constexpr wxPGKeyboardAction wxPG_ACTION_PREV_PROPERTY { wxPGKeyboardAction::PrevProperty }; +wxDEPRECATED_MSG("use wxPGKeyboardAction::ExpandProperty instead") +constexpr wxPGKeyboardAction wxPG_ACTION_EXPAND_PROPERTY { wxPGKeyboardAction::ExpandProperty }; +wxDEPRECATED_MSG("use wxPGKeyboardAction::CollapseProperty instead") +constexpr wxPGKeyboardAction wxPG_ACTION_COLLAPSE_PROPERTY { wxPGKeyboardAction::CollapseProperty }; +wxDEPRECATED_MSG("use wxPGKeyboardAction::CancelEdit instead") +constexpr wxPGKeyboardAction wxPG_ACTION_CANCEL_EDIT { wxPGKeyboardAction::CancelEdit }; +wxDEPRECATED_MSG("use wxPGKeyboardAction::Edit instead") +constexpr wxPGKeyboardAction wxPG_ACTION_EDIT { wxPGKeyboardAction::Edit }; +wxDEPRECATED_MSG("use wxPGKeyboardAction::PressButton instead") +constexpr wxPGKeyboardAction wxPG_ACTION_PRESS_BUTTON { wxPGKeyboardAction::PressButton }; #endif // WXWIN_COMPATIBILITY_3_2 // ----------------------------------------------------------------------- @@ -585,20 +588,20 @@ public: // Adds given key combination to trigger given action. // Here is a sample code to make Enter key press move focus to // the next property. - // propGrid->AddActionTrigger(wxPGKeyboardActions::NextProperty, WXK_RETURN); + // propGrid->AddActionTrigger(wxPGKeyboardAction::NextProperty, WXK_RETURN); // propGrid->DedicateKey(WXK_RETURN); // action - Which action to trigger. See @ref propgrid_keyboard_actions. // keycode - Which keycode triggers the action. // modifiers - Which key event modifiers, in addition to keycode, are needed to // trigger the action. #if WXWIN_COMPATIBILITY_3_2 - wxDEPRECATED_MSG("use AddActionTrigger with 'action' argument as wxPGKeyboardActions") + wxDEPRECATED_MSG("use AddActionTrigger with 'action' argument as wxPGKeyboardAction") void AddActionTrigger(int action, int keycode, int modifiers) { - AddActionTrigger(static_cast(action), keycode, modifiers); + AddActionTrigger(static_cast(action), keycode, modifiers); } #endif // WXWIN_COMPATIBILITY_3_2 - void AddActionTrigger(wxPGKeyboardActions action, int keycode, int modifiers = 0); + void AddActionTrigger(wxPGKeyboardAction action, int keycode, int modifiers = 0); // Dedicates a specific keycode to wxPropertyGrid. This means that such // key presses will not be redirected to editor controls. @@ -632,13 +635,13 @@ public: // Clears action triggers for given action. #if WXWIN_COMPATIBILITY_3_2 - wxDEPRECATED_MSG("use ClearActionTriggers with wxPGKeyboardActions argument") + wxDEPRECATED_MSG("use ClearActionTriggers with wxPGKeyboardAction argument") void ClearActionTriggers(int action) { - ClearActionTriggers(static_cast(action)); + ClearActionTriggers(static_cast(action)); } #endif // WXWIN_COMPATIBILITY_3_2 - void ClearActionTriggers(wxPGKeyboardActions action); + void ClearActionTriggers(wxPGKeyboardAction action); // Forces updating the value of property from the editor control. // Note that wxEVT_PG_CHANGING and wxEVT_PG_CHANGED are dispatched using @@ -1519,7 +1522,7 @@ protected: wxPGValidationInfo m_validationInfo; // Actions and keys that trigger them. - std::unordered_map> m_actionTriggers; + std::unordered_map> m_actionTriggers; // Appearance of currently active editor. wxPGCell m_editorAppearance; @@ -1775,14 +1778,14 @@ protected: unsigned int bottomItemY, const wxRect* itemsRect = nullptr ); - // Translate wxKeyEvent to wxPGKeyboardActions::XXX - std::pair KeyEventToActions(const wxKeyEvent& event) const; + // Translate wxKeyEvent to wxPGKeyboardAction::XXX + std::pair KeyEventToActions(const wxKeyEvent& event) const; #if WXWIN_COMPATIBILITY_3_2 wxDEPRECATED_MSG("use single-argument function KeyEventToActions(event)") - wxPGKeyboardActions KeyEventToActions(wxKeyEvent &event, wxPGKeyboardActions* pSecond) const; + wxPGKeyboardAction KeyEventToActions(wxKeyEvent &event, wxPGKeyboardAction* pSecond) const; #endif // WXWIN_COMPATIBILITY_3_2 - wxPGKeyboardActions KeyEventToAction(wxKeyEvent& event) const; + wxPGKeyboardAction KeyEventToAction(wxKeyEvent& event) const; void ImprovedClientToScreen( int* px, int* py ) const; @@ -1876,7 +1879,7 @@ protected: private: - bool ButtonTriggerKeyTest(wxPGKeyboardActions action, wxKeyEvent& event); + bool ButtonTriggerKeyTest(wxPGKeyboardAction action, wxKeyEvent& event); wxDECLARE_EVENT_TABLE(); }; diff --git a/interface/wx/propgrid/propgrid.h b/interface/wx/propgrid/propgrid.h index c68fda75c8..680a7e7374 100644 --- a/interface/wx/propgrid/propgrid.h +++ b/interface/wx/propgrid/propgrid.h @@ -396,7 +396,7 @@ public: @{ */ -enum class wxPGKeyboardActions +enum class wxPGKeyboardAction { Invalid, @@ -517,7 +517,7 @@ public: the next property. @code - propGrid->AddActionTrigger(wxPGKeyboardActions::NextProperty, + propGrid->AddActionTrigger(wxPGKeyboardAction::NextProperty, WXK_RETURN); propGrid->DedicateKey(WXK_RETURN); @endcode @@ -530,7 +530,7 @@ public: Which key event modifiers, in addition to keycode, are needed to trigger the action. */ - void AddActionTrigger(wxPGKeyboardActions action, int keycode, int modifiers = 0); + void AddActionTrigger(wxPGKeyboardAction action, int keycode, int modifiers = 0); /** Adds given property into selection. If ::wxPG_EX_MULTIPLE_SELECTION @@ -602,7 +602,7 @@ public: @param action Which action to clear. @ref propgrid_keyboard_actions. */ - void ClearActionTriggers(wxPGKeyboardActions action); + void ClearActionTriggers(wxPGKeyboardAction action); /** Forces updating the value of property from the editor control. diff --git a/samples/propgrid/propgrid.cpp b/samples/propgrid/propgrid.cpp index a47e2801b2..9659b12b01 100644 --- a/samples/propgrid/propgrid.cpp +++ b/samples/propgrid/propgrid.cpp @@ -2440,7 +2440,7 @@ void FormMain::OnExtendedKeyNav( wxCommandEvent& WXUNUSED(event) ) // Up, and Down keys for navigating between properties. wxPropertyGrid* propGrid = m_pPropGridManager->GetGrid(); - propGrid->AddActionTrigger(wxPGKeyboardActions::NextProperty, + propGrid->AddActionTrigger(wxPGKeyboardAction::NextProperty, WXK_RETURN); propGrid->DedicateKey(WXK_RETURN); diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 202ee21929..5f902410b7 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -379,15 +379,15 @@ void wxPropertyGrid::Init1() m_unspecifiedAppearance.SetFgCol(*wxLIGHT_GREY); // Set default keys - AddActionTrigger(wxPGKeyboardActions::NextProperty, WXK_RIGHT); - AddActionTrigger(wxPGKeyboardActions::NextProperty, WXK_DOWN); - AddActionTrigger(wxPGKeyboardActions::PrevProperty, WXK_LEFT); - AddActionTrigger(wxPGKeyboardActions::PrevProperty, WXK_UP); - AddActionTrigger(wxPGKeyboardActions::ExpandProperty, WXK_RIGHT); - AddActionTrigger(wxPGKeyboardActions::CollapseProperty, WXK_LEFT); - AddActionTrigger(wxPGKeyboardActions::CancelEdit, WXK_ESCAPE); - AddActionTrigger(wxPGKeyboardActions::PressButton, WXK_DOWN, wxMOD_ALT); - AddActionTrigger(wxPGKeyboardActions::PressButton, WXK_F4); + AddActionTrigger(wxPGKeyboardAction::NextProperty, WXK_RIGHT); + AddActionTrigger(wxPGKeyboardAction::NextProperty, WXK_DOWN); + AddActionTrigger(wxPGKeyboardAction::PrevProperty, WXK_LEFT); + AddActionTrigger(wxPGKeyboardAction::PrevProperty, WXK_UP); + AddActionTrigger(wxPGKeyboardAction::ExpandProperty, WXK_RIGHT); + AddActionTrigger(wxPGKeyboardAction::CollapseProperty, WXK_LEFT); + AddActionTrigger(wxPGKeyboardAction::CancelEdit, WXK_ESCAPE); + AddActionTrigger(wxPGKeyboardAction::PressButton, WXK_DOWN, wxMOD_ALT); + AddActionTrigger(wxPGKeyboardAction::PressButton, WXK_F4); m_coloursCustomized = 0; @@ -5535,9 +5535,9 @@ void wxPropertyGrid::OnMouseUpChild( wxMouseEvent &event ) // wxPropertyGrid keyboard event handling // ----------------------------------------------------------------------- -std::pair wxPropertyGrid::KeyEventToActions(const wxKeyEvent& event) const +std::pair wxPropertyGrid::KeyEventToActions(const wxKeyEvent& event) const { - // Translates wxKeyEvent to wxPGKeyboardActions::XXX + // Translates wxKeyEvent to wxPGKeyboardAction::XXX int keycode = event.GetKeyCode(); int modifiers = event.GetModifiers(); @@ -5549,16 +5549,16 @@ std::pair wxPropertyGrid::KeyEventToAc auto it = m_actionTriggers.find(hashMapKey); if ( it == m_actionTriggers.end() ) - return std::make_pair(wxPGKeyboardActions::Invalid, wxPGKeyboardActions::Invalid); + return std::make_pair(wxPGKeyboardAction::Invalid, wxPGKeyboardAction::Invalid); return it->second; } #if WXWIN_COMPATIBILITY_3_2 -wxPGKeyboardActions wxPropertyGrid::KeyEventToActions(wxKeyEvent &event, wxPGKeyboardActions* pSecond) const +wxPGKeyboardAction wxPropertyGrid::KeyEventToActions(wxKeyEvent &event, wxPGKeyboardAction* pSecond) const { - // Translates wxKeyEvent to wxPGKeyboardActions::XXX - std::pair actions = KeyEventToActions(event); + // Translates wxKeyEvent to wxPGKeyboardAction::XXX + std::pair actions = KeyEventToActions(event); if ( pSecond ) { @@ -5569,18 +5569,18 @@ wxPGKeyboardActions wxPropertyGrid::KeyEventToActions(wxKeyEvent &event, wxPGKey } #endif // WXWIN_COMPATIBILITY_3_2 -wxPGKeyboardActions wxPropertyGrid::KeyEventToAction(wxKeyEvent& event) const +wxPGKeyboardAction wxPropertyGrid::KeyEventToAction(wxKeyEvent& event) const { return KeyEventToActions(event).first; } -void wxPropertyGrid::AddActionTrigger(wxPGKeyboardActions action, int keycode, int modifiers) +void wxPropertyGrid::AddActionTrigger(wxPGKeyboardAction action, int keycode, int modifiers) { wxASSERT( !(modifiers&~(0xFFFF)) ); int hashMapKey = (keycode & 0xFFFF) | ((modifiers & 0xFFFF) << 16); - std::pair curActions; + std::pair curActions; auto it = m_actionTriggers.find(hashMapKey); if ( it != m_actionTriggers.end() ) @@ -5589,20 +5589,20 @@ void wxPropertyGrid::AddActionTrigger(wxPGKeyboardActions action, int keycode, i curActions = it->second; // Can add secondary? - wxASSERT_MSG( curActions.second == wxPGKeyboardActions::Invalid, + wxASSERT_MSG( curActions.second == wxPGKeyboardAction::Invalid, "You can only add up to two separate actions per key combination." ); curActions.second = action; } else { - curActions = std::make_pair(action, wxPGKeyboardActions::Invalid); + curActions = std::make_pair(action, wxPGKeyboardAction::Invalid); } m_actionTriggers[hashMapKey] = curActions; } -void wxPropertyGrid::ClearActionTriggers(wxPGKeyboardActions action) +void wxPropertyGrid::ClearActionTriggers(wxPGKeyboardAction action) { // wxCHECK_RET(!(action & ~(0xFFFF)), wxS("You can only clear triggers for one action at a time.") @@ -5611,12 +5611,12 @@ void wxPropertyGrid::ClearActionTriggers(wxPGKeyboardActions action) { if ( it->second.second == action ) { - it->second.second = wxPGKeyboardActions::Invalid; + it->second.second = wxPGKeyboardAction::Invalid; } if ( it->second.first == action ) { - if ( it->second.second == wxPGKeyboardActions::Invalid ) + if ( it->second.second == wxPGKeyboardAction::Invalid ) { it = m_actionTriggers.erase(it); continue; @@ -5689,11 +5689,11 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) return; } - wxPGKeyboardActions action; - wxPGKeyboardActions secondAction; + wxPGKeyboardAction action; + wxPGKeyboardAction secondAction; std::tie(action, secondAction) = KeyEventToActions(event); - if ( editorFocused && action == wxPGKeyboardActions::CancelEdit ) + if ( editorFocused && action == wxPGKeyboardAction::CancelEdit ) { // // Esc cancels any changes @@ -5737,7 +5737,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) wxPGProperty* p = selected; - if ( action == wxPGKeyboardActions::Edit && !editorFocused ) + if ( action == wxPGKeyboardAction::Edit && !editorFocused ) { // Mark as handled only for editable property if ( !p->IsCategory() && p->IsEnabled() && !p->HasFlag(wxPGPropertyFlags::ReadOnly) ) @@ -5752,12 +5752,12 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) if ( p->GetChildCount() ) { - if ( action == wxPGKeyboardActions::CollapseProperty || secondAction == wxPGKeyboardActions::CollapseProperty ) + if ( action == wxPGKeyboardAction::CollapseProperty || secondAction == wxPGKeyboardAction::CollapseProperty ) { if ( (m_windowStyle & wxPG_HIDE_MARGIN) || DoCollapse(p, true) ) wasHandled = true; } - else if ( action == wxPGKeyboardActions::ExpandProperty || secondAction == wxPGKeyboardActions::ExpandProperty ) + else if ( action == wxPGKeyboardAction::ExpandProperty || secondAction == wxPGKeyboardAction::ExpandProperty ) { if ( (m_windowStyle & wxPG_HIDE_MARGIN) || DoExpand(p, true) ) wasHandled = true; @@ -5766,11 +5766,11 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) if ( !wasHandled ) { - if ( action == wxPGKeyboardActions::PrevProperty || secondAction == wxPGKeyboardActions::PrevProperty ) + if ( action == wxPGKeyboardAction::PrevProperty || secondAction == wxPGKeyboardAction::PrevProperty ) { selectDir = -1; } - else if ( action == wxPGKeyboardActions::NextProperty || secondAction == wxPGKeyboardActions::NextProperty ) + else if ( action == wxPGKeyboardAction::NextProperty || secondAction == wxPGKeyboardAction::NextProperty ) { selectDir = 1; } @@ -5784,7 +5784,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) wxPGSelectPropertyFlags selFlags = wxPGSelectPropertyFlags::Null; int reopenLabelEditorCol = -1; - if ( action == wxPGKeyboardActions::Edit ) + if ( action == wxPGKeyboardAction::Edit ) { // Make the next editor focused as well // if we are actually going to edit the property. @@ -5802,7 +5802,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) if ( reopenLabelEditorCol >= 0 ) DoBeginLabelEdit(reopenLabelEditorCol); } - else if ( action == wxPGKeyboardActions::Edit ) + else if ( action == wxPGKeyboardAction::Edit ) { // For first and last item just validate the value CommitChangesFromEditor(); @@ -5814,7 +5814,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) { // If nothing was selected, select the first item now // (or navigate out of tab). - if ( action != wxPGKeyboardActions::CancelEdit && secondAction != wxPGKeyboardActions::CancelEdit ) + if ( action != wxPGKeyboardAction::CancelEdit && secondAction != wxPGKeyboardAction::CancelEdit ) { wxPGProperty* p = wxPropertyGridInterface::GetFirst(); if ( p ) DoSelectProperty(p); @@ -5848,15 +5848,15 @@ void wxPropertyGrid::OnKey( wxKeyEvent &event ) // ----------------------------------------------------------------------- -bool wxPropertyGrid::ButtonTriggerKeyTest(wxPGKeyboardActions action, wxKeyEvent& event) +bool wxPropertyGrid::ButtonTriggerKeyTest(wxPGKeyboardAction action, wxKeyEvent& event) { - if ( action == wxPGKeyboardActions::Invalid ) + if ( action == wxPGKeyboardAction::Invalid ) { action = KeyEventToActions(event).first; } // Does the keycode trigger button? - if ( action == wxPGKeyboardActions::PressButton && + if ( action == wxPGKeyboardAction::PressButton && m_wndEditor2 ) { wxCommandEvent evt(wxEVT_BUTTON, m_wndEditor2->GetId()); From e2dcdb275b651295b9f75e210d4f9b58be9acaab Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 17:58:22 +0100 Subject: [PATCH 225/257] Use wxString() rather than wxEmptyString in propgrid sample --- samples/propgrid/propgrid.cpp | 15 +++++++-------- samples/propgrid/sampleprops.cpp | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/samples/propgrid/propgrid.cpp b/samples/propgrid/propgrid.cpp index 9659b12b01..79dfd835ca 100644 --- a/samples/propgrid/propgrid.cpp +++ b/samples/propgrid/propgrid.cpp @@ -339,7 +339,7 @@ public: SingleChoiceProperty( const wxString& label, const wxString& name = wxPG_LABEL, - const wxString& value = wxEmptyString ) + const wxString& value = wxString() ) : wxStringProperty(label, name, value) { // Prepare choices @@ -812,7 +812,7 @@ void FormMain::OnPropertyGridItemRightClick( wxPropertyGridEvent& event ) } else { - sb->SetStatusText( wxEmptyString ); + sb->SetStatusText( wxString() ); } #endif } @@ -834,7 +834,7 @@ void FormMain::OnPropertyGridItemDoubleClick( wxPropertyGridEvent& event ) } else { - sb->SetStatusText ( wxEmptyString ); + sb->SetStatusText ( wxString() ); } #endif } @@ -1280,7 +1280,7 @@ void FormMain::PopulateWithExamples () soc.Add( "Look, it continues", 200 ); soc.Add( "Even More", 240 ); soc.Add( "And More", 280 ); - soc.Add( wxEmptyString, 300 ); + soc.Add( "", 300); soc.Add( "True End of the List", 320 ); // Test custom colours ([] operator of wxPGChoices returns @@ -1331,8 +1331,7 @@ void FormMain::PopulateWithExamples () pg->SetPropertyHelpString( "Password", "Has attribute wxPG_STRING_PASSWORD set to true" ); - // String editor with dir selector button. Uses wxEmptyString as name, which - // is allowed (naturally, in this case property cannot be accessed by name). + // String editor with dir selector button. pg->Append( new wxDirProperty( "DirProperty", wxPG_LABEL, ::wxGetUserHome()) ); pg->SetPropertyAttribute( "DirProperty", wxPG_DIALOG_TITLE, @@ -1978,7 +1977,7 @@ FormMain::FormMain(const wxString& title) // // Create menu bar - wxMenu *menuFile = new wxMenu(wxEmptyString, wxMENU_TEAROFF); + wxMenu *menuFile = new wxMenu("", wxMENU_TEAROFF); wxMenu *menuTry = new wxMenu; wxMenu *menuTools1 = new wxMenu; wxMenu *menuTools2 = new wxMenu; @@ -2102,7 +2101,7 @@ FormMain::FormMain(const wxString& title) #if wxUSE_STATUSBAR // create a status bar CreateStatusBar(1); - SetStatusText(wxEmptyString); + SetStatusText(wxString()); #endif // wxUSE_STATUSBAR // Register all editors (SpinCtrl etc.) diff --git a/samples/propgrid/sampleprops.cpp b/samples/propgrid/sampleprops.cpp index d22b46cf75..b305cd82f5 100644 --- a/samples/propgrid/sampleprops.cpp +++ b/samples/propgrid/sampleprops.cpp @@ -557,7 +557,7 @@ bool wxArrayDoubleProperty::DisplayEditorDialog(wxPropertyGrid* pg, wxVariant& v // Create editor dialog. wxArrayDoubleEditorDialog dlg; dlg.SetPrecision(m_precision); - dlg.Create(pg->GetPanel(), wxEmptyString, + dlg.Create(pg->GetPanel(), "", m_dlgTitle.empty() ? GetLabel() : m_dlgTitle, curValue, m_dlgStyle); dlg.Move( pg->GetGoodEditorDialogPosition(this,dlg.GetSize()) ); @@ -710,7 +710,7 @@ wxColour MyColourProperty::GetColour(int index) const wxString MyColourProperty::ColourToString(const wxColour& col, int index, wxPGPropValFormatFlags flags) const { if ( index == (int)(m_choices.GetCount() - 1) ) - return wxEmptyString; + return wxString(); return wxColourProperty::ColourToString(col, index, flags); } From 72a909c9710fb6147b80040f217e5699359873b9 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 18:09:41 +0100 Subject: [PATCH 226/257] Use std::array instead of raw array in wxUIntProperty --- src/propgrid/props.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/propgrid/props.cpp b/src/propgrid/props.cpp index fe6cb2c9b1..6d8a90bfed 100644 --- a/src/propgrid/props.cpp +++ b/src/propgrid/props.cpp @@ -30,6 +30,7 @@ #include #include +#include constexpr double wxPG_DBL_MIN = std::numeric_limits::min(); constexpr double wxPG_DBL_MAX = std::numeric_limits::max(); @@ -603,7 +604,7 @@ wxUIntProperty::wxUIntProperty( const wxString& label, const wxString& name, wxString wxUIntProperty::ValueToString(wxVariant& value, wxPGPropValFormatFlags flags) const { - static const wxStringCharType* const gs_uintTemplates32[wxPG_UINT_TEMPLATE_MAX] = + static constexpr std::array gs_uintTemplates32 { wxS("%lx"), wxS("0x%lx"), wxS("$%lx"), wxS("%lX"), wxS("0x%lX"), wxS("$%lX"), @@ -612,7 +613,7 @@ wxString wxUIntProperty::ValueToString(wxVariant& value, wxPGPropValFormatFlags // In the edit mode we want to display just the numeric value, // without prefixes. - static const wxStringCharType* const gs_uintEditTemplates32[wxPG_UINT_TEMPLATE_MAX] = + static constexpr std::array gs_uintEditTemplates32 { wxS("%lx"), wxS("%lx"), wxS("%lx"), wxS("%lX"), wxS("%lX"), wxS("%lX"), @@ -620,7 +621,7 @@ wxString wxUIntProperty::ValueToString(wxVariant& value, wxPGPropValFormatFlags }; #if wxUSE_LONGLONG - static const wxStringCharType* const gs_uintTemplates64[wxPG_UINT_TEMPLATE_MAX] = + static constexpr std::array gs_uintTemplates64 { wxS("%") wxS(wxLongLongFmtSpec) wxS("x"), wxS("0x%") wxS(wxLongLongFmtSpec) wxS("x"), @@ -634,7 +635,7 @@ wxString wxUIntProperty::ValueToString(wxVariant& value, wxPGPropValFormatFlags // In the edit mode we want to display just the numeric value, // without prefixes. - static const wxStringCharType* const gs_uintEditTemplates64[wxPG_UINT_TEMPLATE_MAX] = + static constexpr std::array gs_uintEditTemplates64 { wxS("%") wxS(wxLongLongFmtSpec) wxS("x"), wxS("%") wxS(wxLongLongFmtSpec) wxS("x"), From 080b778d1788ed00816cf0d03d5f65fafd2c96f6 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 18:14:39 +0100 Subject: [PATCH 227/257] Use std::array instead of raw array in wxColourProperty --- src/propgrid/advprops.cpp | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/propgrid/advprops.cpp b/src/propgrid/advprops.cpp index 2728a7f55d..31708e6cd0 100644 --- a/src/propgrid/advprops.cpp +++ b/src/propgrid/advprops.cpp @@ -31,6 +31,7 @@ #include "wx/uilocale.h" #include +#include // Drawing ARGB on standard DC is supported by OSX and GTK3 #if defined(__WXOSX__) || defined(__WXGTK3__) @@ -1513,7 +1514,8 @@ bool wxSystemColourProperty::DoSetAttribute( const wxString& name, wxVariant& va // wxColourProperty // ----------------------------------------------------------------------- -static const char* const gs_cp_es_normcolour_labels[] = { +static constexpr std::array gs_cp_es_normcolour_labels +{ wxTRANSLATE("Black"), wxTRANSLATE("Maroon"), wxTRANSLATE("Navy"), @@ -1536,7 +1538,13 @@ static const char* const gs_cp_es_normcolour_labels[] = { nullptr }; -static const long gs_cp_es_normcolour_values[] = { +#if wxCHECK_CXX_STD(201402L) // [] is constexpr since C++14 +static_assert(gs_cp_es_normcolour_labels[gs_cp_es_normcolour_labels.size() - 1] == nullptr, + "nullptr has to mark the end of table"); +#endif // >= C++ 14 + +static constexpr std::array gs_cp_es_normcolour_values +{ 0, 1, 2, @@ -1558,7 +1566,8 @@ static const long gs_cp_es_normcolour_values[] = { wxPG_COLOUR_CUSTOM }; -static const unsigned long gs_cp_es_normcolour_colours[] = { +static constexpr std::array gs_cp_es_normcolour_colours +{ wxPG_COLOUR(0,0,0), wxPG_COLOUR(128,0,0), wxPG_COLOUR(0,0,128), @@ -1580,6 +1589,11 @@ static const unsigned long gs_cp_es_normcolour_colours[] = { wxPG_COLOUR(0,0,0) }; +static_assert(gs_cp_es_normcolour_values.size() == gs_cp_es_normcolour_labels.size() - 1, + "Colour values table has to have one item less than colour labels table"); +static_assert(gs_cp_es_normcolour_colours.size() == gs_cp_es_normcolour_values.size(), + "Colours table and colour values table have to have the same size"); + wxPG_IMPLEMENT_PROPERTY_CLASS(wxColourProperty, wxSystemColourProperty, TextCtrlAndButton) @@ -1588,16 +1602,16 @@ static wxPGChoices gs_wxColourProperty_choicesCache; wxColourProperty::wxColourProperty( const wxString& label, const wxString& name, const wxColour& value ) - : wxSystemColourProperty(label, name, gs_cp_es_normcolour_labels, - gs_cp_es_normcolour_values, + : wxSystemColourProperty(label, name, gs_cp_es_normcolour_labels.data(), + gs_cp_es_normcolour_values.data(), &gs_wxColourProperty_choicesCache, value ) { wxASSERT_MSG( wxTheColourDatabase, wxS("No colour database") ); if ( wxTheColourDatabase ) { // Extend colour database with PG-specific colours. - const char* const* colourLabels = gs_cp_es_normcolour_labels; - for ( int i = 0; *colourLabels; colourLabels++, i++ ) + auto colourLabels = gs_cp_es_normcolour_labels.begin(); + for ( int i = 0; *colourLabels; ++colourLabels, i++ ) { // Don't take into account user-defined custom colour. if (gs_cp_es_normcolour_values[i] != wxPG_COLOUR_CUSTOM) From 809567230905b912f0e163a66a911dbfe847ea4d Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 18:19:59 +0100 Subject: [PATCH 228/257] Use std::array instead of raw array in wxSystemColourProperty --- src/propgrid/advprops.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/propgrid/advprops.cpp b/src/propgrid/advprops.cpp index 31708e6cd0..e23c7ce60c 100644 --- a/src/propgrid/advprops.cpp +++ b/src/propgrid/advprops.cpp @@ -766,7 +766,8 @@ void wxFontProperty::OnCustomPaint(wxDC& dc, #include "wx/colordlg.h" -static const char* const gs_cp_es_syscolour_labels[] = { +static constexpr std::array gs_cp_es_syscolour_labels +{ /* TRANSLATORS: Keyword of system colour */ wxTRANSLATE("AppWorkspace"), /* TRANSLATORS: Keyword of system colour */ wxTRANSLATE("ActiveBorder"), /* TRANSLATORS: Keyword of system colour */ wxTRANSLATE("ActiveCaption"), @@ -795,7 +796,13 @@ static const char* const gs_cp_es_syscolour_labels[] = { nullptr }; -static const long gs_cp_es_syscolour_values[] = { +#if wxCHECK_CXX_STD(201402L) // [] is constexpr since C++14 +static_assert(gs_cp_es_syscolour_labels[gs_cp_es_syscolour_labels.size() - 1] == nullptr, + "nullptr has to mark the end of table"); +#endif // >= C++ 14 + +static constexpr std::array gs_cp_es_syscolour_values +{ wxSYS_COLOUR_APPWORKSPACE, wxSYS_COLOUR_ACTIVEBORDER, wxSYS_COLOUR_ACTIVECAPTION, @@ -823,6 +830,8 @@ static const long gs_cp_es_syscolour_values[] = { wxPG_COLOUR_CUSTOM }; +static_assert(gs_cp_es_syscolour_values.size() == gs_cp_es_syscolour_labels.size() - 1, + "Colour values table has to have one item less than colour labels table"); IMPLEMENT_VARIANT_OBJECT_EXPORTED_SHALLOWCMP(wxColourPropertyValue, WXDLLIMPEXP_PROPGRID) @@ -859,8 +868,8 @@ wxSystemColourProperty::wxSystemColourProperty( const wxString& label, const wxS const wxColourPropertyValue& value ) : wxEnumProperty( label, name, - gs_cp_es_syscolour_labels, - gs_cp_es_syscolour_values, + gs_cp_es_syscolour_labels.data(), + gs_cp_es_syscolour_values.data(), &gs_wxSystemColourProperty_choicesCache ) { Init( value.m_type, value.m_colour ); From 084d70fbe26ccfcd947ebe65f167c32a569f2e21 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 18:22:02 +0100 Subject: [PATCH 229/257] Use std::array instead of raw array in wxFontProperty --- src/propgrid/advprops.cpp | 54 ++++++++++++++++++++++++++++++--------- 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/src/propgrid/advprops.cpp b/src/propgrid/advprops.cpp index e23c7ce60c..62f4302444 100644 --- a/src/propgrid/advprops.cpp +++ b/src/propgrid/advprops.cpp @@ -491,35 +491,56 @@ void wxPGDatePickerCtrlEditor::SetValueToUnspecified( wxPGProperty* property, // NB: Do not use wxS here since unlike wxT it doesn't translate to wxChar* // -static const wxChar* const gs_fp_es_family_labels[] = { +static constexpr std::array gs_fp_es_family_labels +{ wxT("Default"), wxT("Decorative"), wxT("Roman"), wxT("Script"), wxT("Swiss"), wxT("Modern"), wxT("Teletype"), wxT("Unknown"), - (const wxChar*) nullptr + nullptr }; -static const long gs_fp_es_family_values[] = { +#if wxCHECK_CXX_STD(201402L) // [] is constexpr since C++14 +static_assert(gs_fp_es_family_labels[gs_fp_es_family_labels.size() - 1] == nullptr, + "nullptr has to mark the end of table"); +#endif // >+ C++ 14 + +static constexpr std::array gs_fp_es_family_values +{ wxFONTFAMILY_DEFAULT, wxFONTFAMILY_DECORATIVE, wxFONTFAMILY_ROMAN, wxFONTFAMILY_SCRIPT, wxFONTFAMILY_SWISS, wxFONTFAMILY_MODERN, wxFONTFAMILY_TELETYPE, wxFONTFAMILY_UNKNOWN }; -static const wxChar* const gs_fp_es_style_labels[] = { +static_assert(gs_fp_es_family_values.size() == gs_fp_es_family_labels.size() - 1, + "Values table has to have one item less than labels table"); + +static constexpr std::array gs_fp_es_style_labels +{ wxT("Normal"), wxT("Slant"), wxT("Italic"), - (const wxChar*) nullptr + nullptr }; -static const long gs_fp_es_style_values[] = { +#if wxCHECK_CXX_STD(201402L) // [] is constexpr since C++14 +static_assert(gs_fp_es_style_labels[gs_fp_es_style_labels.size() - 1] == nullptr, + "nullptr has to mark the end of table"); +#endif // >= C++ 14 + +static constexpr std::array gs_fp_es_style_values +{ wxFONTSTYLE_NORMAL, wxFONTSTYLE_SLANT, wxFONTSTYLE_ITALIC }; -static const wxChar* const gs_fp_es_weight_labels[] = { +static_assert(gs_fp_es_style_values.size() == gs_fp_es_style_labels.size() - 1, + "Values table has to have one item less than labels table"); + +static constexpr std::array gs_fp_es_weight_labels +{ wxT("Thin"), wxT("ExtraLight"), wxT("Light"), @@ -530,10 +551,16 @@ static const wxChar* const gs_fp_es_weight_labels[] = { wxT("ExtraBold"), wxT("Heavy"), wxT("ExtraHeavy"), - (const wxChar*) nullptr + nullptr }; -static const long gs_fp_es_weight_values[] = { +#if wxCHECK_CXX_STD(201402L) // [] is constexpr since C++14 +static_assert(gs_fp_es_weight_labels[gs_fp_es_weight_labels.size() - 1] == nullptr, + "nullptr has to mark the end of table"); +#endif // >= C++ 14 + +static constexpr std::array gs_fp_es_weight_values +{ wxFONTWEIGHT_THIN, wxFONTWEIGHT_EXTRALIGHT, wxFONTWEIGHT_LIGHT, @@ -546,6 +573,9 @@ static const long gs_fp_es_weight_values[] = { wxFONTWEIGHT_EXTRAHEAVY }; +static_assert(gs_fp_es_weight_values.size() == gs_fp_es_weight_labels.size() - 1, + "Values table has to have one item less than labels table"); + // Class body is in advprops.h @@ -591,12 +621,12 @@ wxFontProperty::wxFontProperty( const wxString& label, const wxString& name, /* TRANSLATORS: Label of font style */ AddPrivateChild( new wxEnumProperty(_("Style"), wxS("Style"), - gs_fp_es_style_labels,gs_fp_es_style_values, + gs_fp_es_style_labels.data(), gs_fp_es_style_values.data(), font.GetStyle()) ); /* TRANSLATORS: Label of font weight */ AddPrivateChild( new wxEnumProperty(_("Weight"), wxS("Weight"), - gs_fp_es_weight_labels,gs_fp_es_weight_values, + gs_fp_es_weight_labels.data(), gs_fp_es_weight_values.data(), font.GetWeight()) ); /* TRANSLATORS: Label of underlined font */ @@ -605,7 +635,7 @@ wxFontProperty::wxFontProperty( const wxString& label, const wxString& name, /* TRANSLATORS: Label of font family */ AddPrivateChild( new wxEnumProperty(_("Family"), wxS("PointSize"), - gs_fp_es_family_labels,gs_fp_es_family_values, + gs_fp_es_family_labels.data(), gs_fp_es_family_values.data(), font.GetFamily()) ); } From dc627da250cb1f201311012be491f0eb25340c67 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek <7330332+a-wi@users.noreply.github.com> Date: Sat, 6 Jan 2024 18:23:53 +0100 Subject: [PATCH 230/257] Use std::array instead of raw array in wxCursorProperty --- src/propgrid/advprops.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/propgrid/advprops.cpp b/src/propgrid/advprops.cpp index 62f4302444..360e14d20c 100644 --- a/src/propgrid/advprops.cpp +++ b/src/propgrid/advprops.cpp @@ -1713,9 +1713,8 @@ wxVariant wxColourProperty::DoTranslateVal( wxColourPropertyValue& v ) const #define wxPG_CURSOR_IMAGE_WIDTH 32 #endif -#define NUM_CURSORS 28 - -static const char* const gs_cp_es_syscursors_labels[NUM_CURSORS+1] = { +static constexpr std::array gs_cp_es_syscursors_labels +{ wxTRANSLATE_IN_CONTEXT("system cursor name", "Default"), wxTRANSLATE_IN_CONTEXT("system cursor name", "Arrow"), wxTRANSLATE_IN_CONTEXT("system cursor name", "Right Arrow"), @@ -1747,7 +1746,13 @@ static const char* const gs_cp_es_syscursors_labels[NUM_CURSORS+1] = { nullptr }; -static const long gs_cp_es_syscursors_values[NUM_CURSORS] = { +#if wxCHECK_CXX_STD(201402L) // [] is constexpr since C++14 +static_assert(gs_cp_es_syscursors_labels[gs_cp_es_syscursors_labels.size() - 1] == nullptr, + "nullptr has to mark the end of table"); +#endif // >= C++ 14 + +static constexpr std::array gs_cp_es_syscursors_values +{ wxCURSOR_NONE, wxCURSOR_ARROW, wxCURSOR_RIGHT_ARROW, @@ -1778,6 +1783,9 @@ static const long gs_cp_es_syscursors_values[NUM_CURSORS] = { wxCURSOR_ARROWWAIT }; +static_assert(gs_cp_es_syscursors_values.size() == gs_cp_es_syscursors_labels.size() - 1, + "Values table has to have one item less than labels table"); + wxIMPLEMENT_DYNAMIC_CLASS(wxCursorProperty, wxEnumProperty); static wxPGChoices gs_wxCursorProperty_choicesCache; @@ -1786,8 +1794,8 @@ wxCursorProperty::wxCursorProperty( const wxString& label, const wxString& name, int value ) : wxEnumProperty( label, name, - gs_cp_es_syscursors_labels, - gs_cp_es_syscursors_values, + gs_cp_es_syscursors_labels.data(), + gs_cp_es_syscursors_values.data(), &gs_wxCursorProperty_choicesCache, value ) { @@ -1803,7 +1811,7 @@ wxString wxCursorProperty::ValueToString(wxVariant& value, wxPGPropValFormatFlag wxSize wxCursorProperty::OnMeasureImage( int item ) const { #if wxPG_CAN_DRAW_CURSOR - if ( item != -1 && item < NUM_CURSORS ) + if ( item != -1 && item < static_cast(gs_cp_es_syscursors_values.size()) ) return wxSize(wxPG_CURSOR_IMAGE_WIDTH,wxPG_CURSOR_IMAGE_WIDTH); #else wxUnusedVar(item); @@ -1824,7 +1832,7 @@ void wxCursorProperty::OnCustomPaint( wxDC& dc, { dc.DrawRectangle( rect ); - if ( paintdata.m_choiceItem < NUM_CURSORS ) + if ( paintdata.m_choiceItem < static_cast(gs_cp_es_syscursors_values.size()) ) { wxStockCursor cursorIndex = (wxStockCursor) gs_cp_es_syscursors_values[paintdata.m_choiceItem]; From 0122ce20c4b81d5a50504bb3a0ea3a617be62718 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 23:04:34 +0100 Subject: [PATCH 231/257] Hide operator<<() overloaded for wxBitmapBundle Define it inside this class and not in the global scope. --- include/wx/bmpbndl.h | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/include/wx/bmpbndl.h b/include/wx/bmpbndl.h index 7b60fd9d18..217e2b2afb 100644 --- a/include/wx/bmpbndl.h +++ b/include/wx/bmpbndl.h @@ -17,6 +17,7 @@ class wxBitmapBundleImpl; class WXDLLIMPEXP_FWD_CORE wxIconBundle; class WXDLLIMPEXP_FWD_CORE wxImageList; +class WXDLLIMPEXP_FWD_BASE wxVariant; class WXDLLIMPEXP_FWD_CORE wxWindow; // ---------------------------------------------------------------------------- @@ -155,6 +156,15 @@ public: return GetImpl() == other.GetImpl(); } + // Allow using wxBitmapBundle with wxVariant +#if wxUSE_VARIANT + friend WXDLLIMPEXP_CORE + wxBitmapBundle& operator<<(wxBitmapBundle& value, const wxVariant& variant); + friend WXDLLIMPEXP_CORE + wxVariant& operator<<(wxVariant& variant, const wxBitmapBundle& value); +#endif // wxUSE_VARIANT + + // Implementation only from now on. // Get the bitmap size preferred by the majority of the elements of the @@ -274,19 +284,4 @@ public: virtual wxBitmap GetBitmap(const wxSize& size) = 0; }; -// ---------------------------------------------------------------------------- -// Allow using wxBitmapBundle in wxVariant -// ---------------------------------------------------------------------------- - -#if wxUSE_VARIANT - -class WXDLLIMPEXP_FWD_BASE wxVariant; - -WXDLLIMPEXP_CORE -wxBitmapBundle& operator<<(wxBitmapBundle& value, const wxVariant& variant); -WXDLLIMPEXP_CORE -wxVariant& operator<<(wxVariant& variant, const wxBitmapBundle& value); - -#endif // wxUSE_VARIANT - #endif // _WX_BMPBNDL_H_ From 7f56c7c068496ac1ede9e849d9cadb458f2fc3b2 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 23:05:05 +0100 Subject: [PATCH 232/257] Hide operator<<() and operator>>() overlods for wxLongLong_t And wxULongLong_t. --- include/wx/longlong.h | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/include/wx/longlong.h b/include/wx/longlong.h index cad5c250ae..6762ad08fa 100644 --- a/include/wx/longlong.h +++ b/include/wx/longlong.h @@ -834,7 +834,14 @@ public: class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxLongLongWx&); friend WXDLLIMPEXP_BASE class wxTextInputStream& operator>>(class wxTextInputStream&, wxLongLongWx&); -#endif + +#if wxUSE_LONGLONG_NATIVE + friend WXDLLIMPEXP_BASE + class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxLongLong_t value); + friend WXDLLIMPEXP_BASE + class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxLongLong_t &value); +#endif // wxUSE_LONGLONG_NATIVE +#endif // wxUSE_STREAMS private: // long is at least 32 bits, so represent our 64bit number as 2 longs @@ -1066,7 +1073,14 @@ public: class wxTextOutputStream& operator<<(class wxTextOutputStream&, const wxULongLongWx&); friend WXDLLIMPEXP_BASE class wxTextInputStream& operator>>(class wxTextInputStream&, wxULongLongWx&); -#endif + +#if wxUSE_LONGLONG_NATIVE + friend WXDLLIMPEXP_BASE + class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxULongLong_t value); + friend WXDLLIMPEXP_BASE + class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxULongLong_t &value); +#endif // wxUSE_LONGLONG_NATIVE +#endif // wxUSE_STREAMS private: // long is at least 32 bits, so represent our 64bit number as 2 longs @@ -1086,16 +1100,6 @@ private: #endif // wxUSE_LONGLONG_WX -#if wxUSE_LONGLONG_NATIVE && wxUSE_STREAMS - -WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxULongLong_t value); -WXDLLIMPEXP_BASE class wxTextOutputStream &operator<<(class wxTextOutputStream &stream, wxLongLong_t value); - -WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxULongLong_t &value); -WXDLLIMPEXP_BASE class wxTextInputStream &operator>>(class wxTextInputStream &stream, wxLongLong_t &value); - -#endif - // ---------------------------------------------------------------------------- // Specialize numeric_limits<> for our long long wrapper classes. // ---------------------------------------------------------------------------- From 09eff033d90106b496c18b402b83d6c447bf4b13 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 20:11:30 +0100 Subject: [PATCH 233/257] Hide operator<<() overloads used for wxVariant support too Add new wxDECLARE_VARIANT_OBJECT_EXPORTED() macro defining these operators as friend functions inside the class declaration and replace all uses of DECLARE_VARIANT_OBJECT_EXPORTED() inside the core library with the new macro to avoid defining any operator<<() overloads in the global scope. Also add wxIMPLEMENT_VARIANT_OBJECT() for consistency, even though it is not really needed. --- include/wx/bitmap.h | 13 ++++--------- include/wx/colour.h | 12 +++--------- include/wx/dvrenderers.h | 8 ++++---- include/wx/generic/icon.h | 2 ++ include/wx/icon.h | 12 +----------- include/wx/image.h | 13 ++++--------- include/wx/msw/icon.h | 2 ++ include/wx/propgrid/advprops.h | 4 ++-- include/wx/variant.h | 25 ++++++++++++++++++++++++- interface/wx/variant.h | 26 +++++++++++++++++--------- 10 files changed, 63 insertions(+), 54 deletions(-) diff --git a/include/wx/bitmap.h b/include/wx/bitmap.h index 3a9f63aa1f..185513b31a 100644 --- a/include/wx/bitmap.h +++ b/include/wx/bitmap.h @@ -18,6 +18,7 @@ #include "wx/gdicmn.h" // for wxBitmapType #include "wx/colour.h" #include "wx/image.h" +#include "wx/variant.h" class WXDLLIMPEXP_FWD_CORE wxBitmap; class WXDLLIMPEXP_FWD_CORE wxBitmapHandler; @@ -28,15 +29,6 @@ class WXDLLIMPEXP_FWD_CORE wxMask; class WXDLLIMPEXP_FWD_CORE wxPalette; class WXDLLIMPEXP_FWD_CORE wxPixelDataBase; -// ---------------------------------------------------------------------------- -// wxVariant support -// ---------------------------------------------------------------------------- - -#if wxUSE_VARIANT -#include "wx/variant.h" -DECLARE_VARIANT_OBJECT_EXPORTED(wxBitmap,WXDLLIMPEXP_CORE) -#endif - // ---------------------------------------------------------------------------- // wxMask represents the transparent area of the bitmap // ---------------------------------------------------------------------------- @@ -100,6 +92,9 @@ public: // Rescale the given bitmap to the requested size. static void Rescale(wxBitmap& bmp, const wxSize& sizeNeeded); + + // wxVariant support + wxDECLARE_VARIANT_OBJECT_EXPORTED(wxBitmap, WXDLLIMPEXP_CORE); }; diff --git a/include/wx/colour.h b/include/wx/colour.h index 344ecc9741..cf1d679890 100644 --- a/include/wx/colour.h +++ b/include/wx/colour.h @@ -13,6 +13,7 @@ #include "wx/defs.h" #include "wx/gdiobj.h" +#include "wx/variant.h" class WXDLLIMPEXP_FWD_CORE wxColour; @@ -53,15 +54,6 @@ const unsigned char wxALPHA_OPAQUE = 0xff; #define wxTransparentColour wxColour(0, 0, 0, wxALPHA_TRANSPARENT) #define wxTransparentColor wxTransparentColour -// ---------------------------------------------------------------------------- -// wxVariant support -// ---------------------------------------------------------------------------- - -#if wxUSE_VARIANT -#include "wx/variant.h" -DECLARE_VARIANT_OBJECT_EXPORTED(wxColour,WXDLLIMPEXP_CORE) -#endif - //----------------------------------------------------------------------------- // wxColourBase: this class has no data members, just some functions to avoid // code redundancy in all native wxColour implementations @@ -188,6 +180,8 @@ public: wxColour ChangeLightness(int ialpha) const; wxColour& MakeDisabled(unsigned char brightness = 255); + wxDECLARE_VARIANT_OBJECT_EXPORTED(wxColour, WXDLLIMPEXP_CORE); + protected: // Some ports need Init() and while we don't, provide a stub so that the // ports which don't need it are not forced to define it diff --git a/include/wx/dvrenderers.h b/include/wx/dvrenderers.h index 8832396fca..e44e874d6f 100644 --- a/include/wx/dvrenderers.h +++ b/include/wx/dvrenderers.h @@ -67,6 +67,8 @@ public: return !IsSameAs(other); } + wxDECLARE_VARIANT_OBJECT_EXPORTED(wxDataViewIconText, WXDLLIMPEXP_CORE); + private: wxString m_text; wxBitmapBundle m_bitmap; @@ -74,8 +76,6 @@ private: wxDECLARE_DYNAMIC_CLASS(wxDataViewIconText); }; -DECLARE_VARIANT_OBJECT_EXPORTED(wxDataViewIconText, WXDLLIMPEXP_CORE) - // ---------------------------------------------------------------------------- // wxDataViewCheckIconText: value class used by wxDataViewCheckIconTextRenderer // ---------------------------------------------------------------------------- @@ -94,14 +94,14 @@ public: wxCheckBoxState GetCheckedState() const { return m_checkedState; } void SetCheckedState(wxCheckBoxState state) { m_checkedState = state; } + wxDECLARE_VARIANT_OBJECT_EXPORTED(wxDataViewCheckIconText, WXDLLIMPEXP_CORE); + private: wxCheckBoxState m_checkedState; wxDECLARE_DYNAMIC_CLASS(wxDataViewCheckIconText); }; -DECLARE_VARIANT_OBJECT_EXPORTED(wxDataViewCheckIconText, WXDLLIMPEXP_CORE) - // ---------------------------------------------------------------------------- // wxDataViewRendererBase // ---------------------------------------------------------------------------- diff --git a/include/wx/generic/icon.h b/include/wx/generic/icon.h index 0138dfeb5b..14fe70acfe 100644 --- a/include/wx/generic/icon.h +++ b/include/wx/generic/icon.h @@ -51,6 +51,8 @@ public: // ctors, assignment operators...), but it's ok to have such function void CopyFromBitmap(const wxBitmap& bmp); + wxDECLARE_VARIANT_OBJECT_EXPORTED(wxIcon, WXDLLIMPEXP_CORE); + private: wxDECLARE_DYNAMIC_CLASS(wxIcon); }; diff --git a/include/wx/icon.h b/include/wx/icon.h index dbc1ed5f4b..d8576e9e04 100644 --- a/include/wx/icon.h +++ b/include/wx/icon.h @@ -11,7 +11,7 @@ #define _WX_ICON_H_BASE_ #include "wx/iconloc.h" - +#include "wx/variant.h" // a more readable way to tell #define wxICON_SCREEN_DEPTH (-1) @@ -57,15 +57,5 @@ #define wxICON_IS_BITMAP #endif -//----------------------------------------------------------------------------- -// wxVariant support -//----------------------------------------------------------------------------- - -#if wxUSE_VARIANT -#include "wx/variant.h" -DECLARE_VARIANT_OBJECT_EXPORTED(wxIcon,WXDLLIMPEXP_CORE) -#endif - - #endif // _WX_ICON_H_BASE_ diff --git a/include/wx/image.h b/include/wx/image.h index 0f1ad39a29..8e34f651a2 100644 --- a/include/wx/image.h +++ b/include/wx/image.h @@ -18,6 +18,7 @@ #include "wx/gdicmn.h" #include "wx/hashmap.h" #include "wx/arrstr.h" +#include "wx/variant.h" #if wxUSE_STREAMS # include "wx/stream.h" @@ -98,15 +99,6 @@ class WXDLLIMPEXP_FWD_CORE wxImageHandler; class WXDLLIMPEXP_FWD_CORE wxImage; class WXDLLIMPEXP_FWD_CORE wxPalette; -//----------------------------------------------------------------------------- -// wxVariant support -//----------------------------------------------------------------------------- - -#if wxUSE_VARIANT -#include "wx/variant.h" -DECLARE_VARIANT_OBJECT_EXPORTED(wxImage,WXDLLIMPEXP_CORE) -#endif - //----------------------------------------------------------------------------- // wxImageHandler //----------------------------------------------------------------------------- @@ -594,6 +586,9 @@ public: static HSVValue RGBtoHSV(const RGBValue& rgb); static RGBValue HSVtoRGB(const HSVValue& hsv); + // wxVariant support + wxDECLARE_VARIANT_OBJECT_EXPORTED(wxImage, WXDLLIMPEXP_CORE); + protected: static wxList sm_handlers; diff --git a/include/wx/msw/icon.h b/include/wx/msw/icon.h index bb13e27d98..fea6ff68a4 100644 --- a/include/wx/msw/icon.h +++ b/include/wx/msw/icon.h @@ -77,6 +77,8 @@ public: // ctors, assignment operators...), but it's ok to have such function void CopyFromBitmap(const wxBitmap& bmp); + wxDECLARE_VARIANT_OBJECT_EXPORTED(wxIcon, WXDLLIMPEXP_CORE); + protected: virtual wxGDIImageRefData *CreateData() const override { diff --git a/include/wx/propgrid/advprops.h b/include/wx/propgrid/advprops.h index f5375997be..d4838fefa5 100644 --- a/include/wx/propgrid/advprops.h +++ b/include/wx/propgrid/advprops.h @@ -113,6 +113,8 @@ public: Init( cpv.m_type, cpv.m_colour ); } + wxDECLARE_VARIANT_OBJECT_EXPORTED(wxColourPropertyValue, WXDLLIMPEXP_PROPGRID); + private: wxDECLARE_DYNAMIC_CLASS(wxColourPropertyValue); }; @@ -121,8 +123,6 @@ private: bool WXDLLIMPEXP_PROPGRID operator==(const wxColourPropertyValue&, const wxColourPropertyValue&); -DECLARE_VARIANT_OBJECT_EXPORTED(wxColourPropertyValue, WXDLLIMPEXP_PROPGRID) - // ----------------------------------------------------------------------- // Property representing wxFont. diff --git a/include/wx/variant.h b/include/wx/variant.h index 4d5f1fe44c..74a623a1ce 100644 --- a/include/wx/variant.h +++ b/include/wx/variant.h @@ -470,7 +470,16 @@ REGISTER_WXANY_CONVERSION(T, CLASSNAME) #endif // wxUSE_ANY/!wxUSE_ANY +// Note: these macros must be used inside "classname" declaration. +#define wxDECLARE_VARIANT_OBJECT(classname) \ + wxDECLARE_VARIANT_OBJECT_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE) +#define wxDECLARE_VARIANT_OBJECT_EXPORTED(classname,expdecl) \ + friend expdecl classname& operator<<(classname &object, const wxVariant &variant); \ + friend expdecl wxVariant& operator<<(wxVariant &variant, const classname &object) + +// These macros are deprecated, consider using wxDECLARE_VARIANT_OBJECT() above +// instead. #define DECLARE_VARIANT_OBJECT(classname) \ DECLARE_VARIANT_OBJECT_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE) @@ -478,6 +487,13 @@ REGISTER_WXANY_CONVERSION(T, CLASSNAME) expdecl classname& operator << ( classname &object, const wxVariant &variant ); \ expdecl wxVariant& operator << ( wxVariant &variant, const classname &object ); +// These macros use "wx" prefix and require a semicolon after them for +// consistency with the rest of wx macros, but are otherwise the same as the +// older IMPLEMENT_VARIANT_XXX macros. +#define wxIMPLEMENT_VARIANT_OBJECT(classname) \ + IMPLEMENT_VARIANT_OBJECT_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE) \ + struct wxDummyVariantStructFwdDecl /* to force a semicolon */ + #define IMPLEMENT_VARIANT_OBJECT(classname) \ IMPLEMENT_VARIANT_OBJECT_EXPORTED(classname, wxEMPTY_PARAMETER_VALUE) @@ -578,6 +594,13 @@ bool classname##VariantData::Eq(wxVariantData& data) const \ extern wxVariant WXDLLIMPEXP_BASE wxNullVariant; -#endif // wxUSE_VARIANT +#else // !wxUSE_VARIANT + +// Define these macros to allow using them without checking for wxUSE_VARIANT +// and simply do nothing in them in this case. +#define wxDECLARE_VARIANT_OBJECT(classname) +#define wxDECLARE_VARIANT_OBJECT_EXPORTED(classname,expdecl) + +#endif // wxUSE_VARIANT/!wxUSE_VARIANT #endif // _WX_VARIANT_H_ diff --git a/interface/wx/variant.h b/interface/wx/variant.h index 08c61c49f8..60b7158c90 100644 --- a/interface/wx/variant.h +++ b/interface/wx/variant.h @@ -42,21 +42,24 @@ required. Note that as of wxWidgets 2.7.1, wxVariant is - @ref overview_refcount "reference counted". Additionally, the convenience - macros DECLARE_VARIANT_OBJECT() and IMPLEMENT_VARIANT_OBJECT() were added - so that adding (limited) support for conversion to and from wxVariant can - be very easily implemented without modifying either wxVariant or the class - to be stored by wxVariant. Since assignment operators cannot be declared - outside the class, the shift left operators are used like this: + @ref overview_refcount "reference counted". + + Convenience macros wxDECLARE_VARIANT_OBJECT() and wxIMPLEMENT_VARIANT_OBJECT() + allow easily adding support for conversion to and from wxVariant to custom + classes. The first of these macros must be used inside the class declaration + and the second one outside of it in the implementation file, e.g. @code // in the header file - DECLARE_VARIANT_OBJECT(MyClass) + class MyClass : public wxObject { + ... + wxDECLARE_VARIANT_OBJECT(MyClass); + }; // in the implementation file - IMPLEMENT_VARIANT_OBJECT(MyClass) + wxIMPLEMENT_VARIANT_OBJECT(MyClass); - // in the user code + // and then objects of MyClass can be used with wxVariant like this: wxVariant variant; MyClass value; variant << value; @@ -79,6 +82,11 @@ - wxBitmap - wxBitmapBundle + @note There also are legacy versions of the above macros without `wx` + prefix, working in a slightly different way. Please use the new + versions in the new code and consider replacing any existing use of + the legacy macros with the new ones. + Note that as of wxWidgets 2.9.0, wxVariantData no longer inherits from wxObject and wxVariant no longer uses the type-unsafe wxList class for list operations but the type-safe wxVariantList class. Also, wxVariantData now From a763de6940d550efbeeeee92087c1f01e8a41402 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 22:57:17 +0100 Subject: [PATCH 234/257] Hide operator+() overloads for wxString::iterator and related Don't define these operators in the global scope. --- include/wx/string.h | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/include/wx/string.h b/include/wx/string.h index 32b99c4ec2..31affce6fe 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -864,6 +864,8 @@ public: iterator operator+(ptrdiff_t n) const { return iterator(str(), wxStringOperations::AddToIter(m_cur, n)); } + friend iterator operator+(ptrdiff_t n, iterator i) + { return i + n; } iterator operator-(ptrdiff_t n) const { return iterator(str(), wxStringOperations::AddToIter(m_cur, -n)); } @@ -918,6 +920,8 @@ public: const_iterator operator+(ptrdiff_t n) const { return const_iterator(str(), wxStringOperations::AddToIter(m_cur, n)); } + friend const_iterator operator+(ptrdiff_t n, const_iterator i) + { return i + n; } const_iterator operator-(ptrdiff_t n) const { return const_iterator(str(), wxStringOperations::AddToIter(m_cur, -n)); } @@ -961,6 +965,8 @@ public: iterator operator+(ptrdiff_t n) const { return iterator(wxStringOperations::AddToIter(m_cur, n)); } + friend iterator operator+(ptrdiff_t n, iterator i) + { return i + n; } iterator operator-(ptrdiff_t n) const { return iterator(wxStringOperations::AddToIter(m_cur, -n)); } @@ -996,6 +1002,8 @@ public: const_iterator operator+(ptrdiff_t n) const { return const_iterator(wxStringOperations::AddToIter(m_cur, n)); } + friend const_iterator operator+(ptrdiff_t n, const_iterator i) + { return i + n; } const_iterator operator-(ptrdiff_t n) const { return const_iterator(wxStringOperations::AddToIter(m_cur, -n)); } @@ -1087,6 +1095,8 @@ public: reverse_iterator_impl operator+(ptrdiff_t n) const { return reverse_iterator_impl(m_cur - n); } + friend iterator operator+(ptrdiff_t n, reverse_iterator_impl i) + { return i + n; } reverse_iterator_impl operator-(ptrdiff_t n) const { return reverse_iterator_impl(m_cur + n); } reverse_iterator_impl operator+=(ptrdiff_t n) @@ -3760,17 +3770,6 @@ private: friend class wxStringInternalBufferLength; }; -// string iterator operators that satisfy STL Random Access Iterator -// requirements: -inline wxString::iterator operator+(ptrdiff_t n, wxString::iterator i) - { return i + n; } -inline wxString::const_iterator operator+(ptrdiff_t n, wxString::const_iterator i) - { return i + n; } -inline wxString::reverse_iterator operator+(ptrdiff_t n, wxString::reverse_iterator i) - { return i + n; } -inline wxString::const_reverse_iterator operator+(ptrdiff_t n, wxString::const_reverse_iterator i) - { return i + n; } - #define wxGetEmptyString() wxString() // ---------------------------------------------------------------------------- From 3c151ac8154a45c5a54b2d5a7355184cf3326ab0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 22:59:45 +0100 Subject: [PATCH 235/257] Hide overloaded operators on wxPoint2DInt and wxPoint2DDouble Define all the arithmetic operators working with these objects inside the corresponding classes and not at the global scope. --- include/wx/geometry.h | 232 +++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 127 deletions(-) diff --git a/include/wx/geometry.h b/include/wx/geometry.h index 34a414ff01..58ec552b56 100644 --- a/include/wx/geometry.h +++ b/include/wx/geometry.h @@ -71,6 +71,60 @@ public : inline bool operator==(const wxPoint2DInt& pt) const; inline bool operator!=(const wxPoint2DInt& pt) const; + friend wxPoint2DInt operator+(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2) + { + return wxPoint2DInt( pt1.m_x + pt2.m_x , pt1.m_y + pt2.m_y ); + } + + friend wxPoint2DInt operator-(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2) + { + return wxPoint2DInt( pt1.m_x - pt2.m_x , pt1.m_y - pt2.m_y ); + } + + + friend wxPoint2DInt operator*(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2) + { + return wxPoint2DInt( pt1.m_x * pt2.m_x , pt1.m_y * pt2.m_y ); + } + + friend wxPoint2DInt operator*(wxInt32 n , const wxPoint2DInt& pt) + { + return wxPoint2DInt( pt.m_x * n , pt.m_y * n ); + } + + friend wxPoint2DInt operator*(wxDouble n , const wxPoint2DInt& pt) + { + return wxPoint2DInt( static_cast(pt.m_x * n) , + static_cast(pt.m_y * n) ); + } + + friend wxPoint2DInt operator*(const wxPoint2DInt& pt , wxInt32 n) + { + return wxPoint2DInt( pt.m_x * n , pt.m_y * n ); + } + + friend wxPoint2DInt operator*(const wxPoint2DInt& pt , wxDouble n) + { + return wxPoint2DInt( static_cast(pt.m_x * n) , + static_cast(pt.m_y * n) ); + } + + friend wxPoint2DInt operator/(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2) + { + return wxPoint2DInt( pt1.m_x / pt2.m_x , pt1.m_y / pt2.m_y ); + } + + friend wxPoint2DInt operator/(const wxPoint2DInt& pt , wxInt32 n) + { + return wxPoint2DInt( pt.m_x / n , pt.m_y / n ); + } + + friend wxPoint2DInt operator/(const wxPoint2DInt& pt , wxDouble n) + { + return wxPoint2DInt( static_cast(pt.m_x / n) , + static_cast(pt.m_y / n) ); + } + #if wxUSE_STREAMS void WriteTo( wxDataOutputStream &stream ) const; void ReadFrom( wxDataInputStream &stream ); @@ -80,17 +134,6 @@ public : wxInt32 m_y; }; -inline wxPoint2DInt operator+(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2); -inline wxPoint2DInt operator-(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2); -inline wxPoint2DInt operator*(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2); -inline wxPoint2DInt operator*(wxInt32 n , const wxPoint2DInt& pt); -inline wxPoint2DInt operator*(wxDouble n , const wxPoint2DInt& pt); -inline wxPoint2DInt operator*(const wxPoint2DInt& pt , wxInt32 n); -inline wxPoint2DInt operator*(const wxPoint2DInt& pt , wxDouble n); -inline wxPoint2DInt operator/(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2); -inline wxPoint2DInt operator/(const wxPoint2DInt& pt , wxInt32 n); -inline wxPoint2DInt operator/(const wxPoint2DInt& pt , wxDouble n); - inline wxPoint2DInt::wxPoint2DInt() { m_x = 0; @@ -209,60 +252,6 @@ inline bool wxPoint2DInt::operator!=(const wxPoint2DInt& pt) const return m_x != pt.m_x || m_y != pt.m_y; } -inline wxPoint2DInt operator+(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2) -{ - return wxPoint2DInt( pt1.m_x + pt2.m_x , pt1.m_y + pt2.m_y ); -} - -inline wxPoint2DInt operator-(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2) -{ - return wxPoint2DInt( pt1.m_x - pt2.m_x , pt1.m_y - pt2.m_y ); -} - - -inline wxPoint2DInt operator*(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2) -{ - return wxPoint2DInt( pt1.m_x * pt2.m_x , pt1.m_y * pt2.m_y ); -} - -inline wxPoint2DInt operator*(wxInt32 n , const wxPoint2DInt& pt) -{ - return wxPoint2DInt( pt.m_x * n , pt.m_y * n ); -} - -inline wxPoint2DInt operator*(wxDouble n , const wxPoint2DInt& pt) -{ - return wxPoint2DInt( static_cast(pt.m_x * n) , - static_cast(pt.m_y * n) ); -} - -inline wxPoint2DInt operator*(const wxPoint2DInt& pt , wxInt32 n) -{ - return wxPoint2DInt( pt.m_x * n , pt.m_y * n ); -} - -inline wxPoint2DInt operator*(const wxPoint2DInt& pt , wxDouble n) -{ - return wxPoint2DInt( static_cast(pt.m_x * n) , - static_cast(pt.m_y * n) ); -} - -inline wxPoint2DInt operator/(const wxPoint2DInt& pt1 , const wxPoint2DInt& pt2) -{ - return wxPoint2DInt( pt1.m_x / pt2.m_x , pt1.m_y / pt2.m_y ); -} - -inline wxPoint2DInt operator/(const wxPoint2DInt& pt , wxInt32 n) -{ - return wxPoint2DInt( pt.m_x / n , pt.m_y / n ); -} - -inline wxPoint2DInt operator/(const wxPoint2DInt& pt , wxDouble n) -{ - return wxPoint2DInt( static_cast(pt.m_x / n) , - static_cast(pt.m_y / n) ); -} - // wxPoint2Ds represent a point or a vector in a 2d coordinate system class WXDLLIMPEXP_CORE wxPoint2DDouble @@ -307,21 +296,61 @@ public : inline bool operator==(const wxPoint2DDouble& pt) const; inline bool operator!=(const wxPoint2DDouble& pt) const; + friend wxPoint2DDouble operator+(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2) + { + return wxPoint2DDouble( pt1.m_x + pt2.m_x , pt1.m_y + pt2.m_y ); + } + + friend wxPoint2DDouble operator-(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2) + { + return wxPoint2DDouble( pt1.m_x - pt2.m_x , pt1.m_y - pt2.m_y ); + } + + + friend wxPoint2DDouble operator*(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2) + { + return wxPoint2DDouble( pt1.m_x * pt2.m_x , pt1.m_y * pt2.m_y ); + } + + friend wxPoint2DDouble operator*(wxDouble n , const wxPoint2DDouble& pt) + { + return wxPoint2DDouble( pt.m_x * n , pt.m_y * n ); + } + + friend wxPoint2DDouble operator*(wxInt32 n , const wxPoint2DDouble& pt) + { + return wxPoint2DDouble( pt.m_x * n , pt.m_y * n ); + } + + friend wxPoint2DDouble operator*(const wxPoint2DDouble& pt , wxDouble n) + { + return wxPoint2DDouble( pt.m_x * n , pt.m_y * n ); + } + + friend wxPoint2DDouble operator*(const wxPoint2DDouble& pt , wxInt32 n) + { + return wxPoint2DDouble( pt.m_x * n , pt.m_y * n ); + } + + friend wxPoint2DDouble operator/(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2) + { + return wxPoint2DDouble( pt1.m_x / pt2.m_x , pt1.m_y / pt2.m_y ); + } + + friend wxPoint2DDouble operator/(const wxPoint2DDouble& pt , wxDouble n) + { + return wxPoint2DDouble( pt.m_x / n , pt.m_y / n ); + } + + friend wxPoint2DDouble operator/(const wxPoint2DDouble& pt , wxInt32 n) + { + return wxPoint2DDouble( pt.m_x / n , pt.m_y / n ); + } + wxDouble m_x; wxDouble m_y; }; -inline wxPoint2DDouble operator+(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2); -inline wxPoint2DDouble operator-(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2); -inline wxPoint2DDouble operator*(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2); -inline wxPoint2DDouble operator*(wxDouble n , const wxPoint2DDouble& pt); -inline wxPoint2DDouble operator*(wxInt32 n , const wxPoint2DDouble& pt); -inline wxPoint2DDouble operator*(const wxPoint2DDouble& pt , wxDouble n); -inline wxPoint2DDouble operator*(const wxPoint2DDouble& pt , wxInt32 n); -inline wxPoint2DDouble operator/(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2); -inline wxPoint2DDouble operator/(const wxPoint2DDouble& pt , wxDouble n); -inline wxPoint2DDouble operator/(const wxPoint2DDouble& pt , wxInt32 n); - inline wxPoint2DDouble::wxPoint2DDouble() { m_x = 0.0; @@ -426,57 +455,6 @@ inline bool wxPoint2DDouble::operator!=(const wxPoint2DDouble& pt) const return !(*this == pt); } -inline wxPoint2DDouble operator+(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2) -{ - return wxPoint2DDouble( pt1.m_x + pt2.m_x , pt1.m_y + pt2.m_y ); -} - -inline wxPoint2DDouble operator-(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2) -{ - return wxPoint2DDouble( pt1.m_x - pt2.m_x , pt1.m_y - pt2.m_y ); -} - - -inline wxPoint2DDouble operator*(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2) -{ - return wxPoint2DDouble( pt1.m_x * pt2.m_x , pt1.m_y * pt2.m_y ); -} - -inline wxPoint2DDouble operator*(wxDouble n , const wxPoint2DDouble& pt) -{ - return wxPoint2DDouble( pt.m_x * n , pt.m_y * n ); -} - -inline wxPoint2DDouble operator*(wxInt32 n , const wxPoint2DDouble& pt) -{ - return wxPoint2DDouble( pt.m_x * n , pt.m_y * n ); -} - -inline wxPoint2DDouble operator*(const wxPoint2DDouble& pt , wxDouble n) -{ - return wxPoint2DDouble( pt.m_x * n , pt.m_y * n ); -} - -inline wxPoint2DDouble operator*(const wxPoint2DDouble& pt , wxInt32 n) -{ - return wxPoint2DDouble( pt.m_x * n , pt.m_y * n ); -} - -inline wxPoint2DDouble operator/(const wxPoint2DDouble& pt1 , const wxPoint2DDouble& pt2) -{ - return wxPoint2DDouble( pt1.m_x / pt2.m_x , pt1.m_y / pt2.m_y ); -} - -inline wxPoint2DDouble operator/(const wxPoint2DDouble& pt , wxDouble n) -{ - return wxPoint2DDouble( pt.m_x / n , pt.m_y / n ); -} - -inline wxPoint2DDouble operator/(const wxPoint2DDouble& pt , wxInt32 n) -{ - return wxPoint2DDouble( pt.m_x / n , pt.m_y / n ); -} - // wxRect2Ds are an axis-aligned rectangles, each side of the rect is parallel to the x- or m_y- axis. The rectangle is either defined by the // top left and bottom right corner, or by the top left corner and size. A point is contained within the rectangle if // left <= x < right and top <= m_y < bottom , thus it is a half open interval. From 3b62433a3f097f73a23a69477322360aedb112ea Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 23:02:45 +0100 Subject: [PATCH 236/257] Hide overloaded wxTimeSpan and wxDateSpan operator*() Define them in these classes scope instead of at the global scope. --- include/wx/datetime.h | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/include/wx/datetime.h b/include/wx/datetime.h index 6e39ce424b..4f9d5cfab9 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -1278,6 +1278,8 @@ public: return wxTimeSpan(*this).Multiply(n); } + friend WXDLLIMPEXP_BASE wxTimeSpan operator*(int n, const wxTimeSpan& ts); + // return this timespan with opposite sign wxTimeSpan Negate() const { return wxTimeSpan(-GetValue()); } // negate the value of the timespan @@ -1531,6 +1533,7 @@ public: { return wxDateSpan(*this).Multiply(n); } + friend WXDLLIMPEXP_BASE wxDateSpan operator*(int n, const wxDateSpan& ds); // ds1 == d2 if and only if for every wxDateTime t t + ds1 == t + ds2 inline bool operator==(const wxDateSpan& ds) const @@ -2243,22 +2246,6 @@ inline wxDateSpan wxDateSpan::Subtract(const wxDateSpan& other) const #undef MODIFY_AND_RETURN -// ============================================================================ -// binary operators -// ============================================================================ - -// ---------------------------------------------------------------------------- -// wxTimeSpan operators -// ---------------------------------------------------------------------------- - -wxTimeSpan WXDLLIMPEXP_BASE operator*(int n, const wxTimeSpan& ts); - -// ---------------------------------------------------------------------------- -// wxDateSpan -// ---------------------------------------------------------------------------- - -wxDateSpan WXDLLIMPEXP_BASE operator*(int n, const wxDateSpan& ds); - // ============================================================================ // other helper functions // ============================================================================ From 2349586e2881211aa1668ce210ecfa0a32c87efd Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sat, 6 Jan 2024 23:04:27 +0100 Subject: [PATCH 237/257] Hide operator<<() overloads for wxString and related classes As not defining operator<<() overload taking wxScopedCharBuffer in the global scope prevents it from being considered as an overload resolution candidate (which is, of course, the whole point), it also prevents it from being used for the classes convertible to it, such as wxCharBuffer, so we need to define operator<<() overloaded for the latter explicitly too. We also need a new wxScopedCharTypeBufferStreamSupport helper in order to define different operators inside different specializations of wxScopedCharTypeBuffer<>. --- include/wx/buffer.h | 77 +++++++++++++++++++++++++++++++++++++++++++ include/wx/string.h | 35 ++++++++------------ src/common/string.cpp | 24 ++++++++++++-- 3 files changed, 112 insertions(+), 24 deletions(-) diff --git a/include/wx/buffer.h b/include/wx/buffer.h index 294fb4e9d7..053e39a105 100644 --- a/include/wx/buffer.h +++ b/include/wx/buffer.h @@ -13,6 +13,10 @@ #include "wx/defs.h" #include "wx/wxcrtbase.h" +#if wxUSE_STD_IOSTREAM + #include "wx/iosfwrap.h" +#endif + #include // malloc() and free() class WXDLLIMPEXP_FWD_BASE wxCStrData; @@ -55,14 +59,70 @@ struct UntypedBufferData // NB: this is defined in string.cpp and not the (non-existent) buffer.cpp WXDLLIMPEXP_BASE UntypedBufferData * GetUntypedNullData(); +// Implementation of stream insertion operators: they can't be inline because +// we don't have full std::ostream declaration here. +#if wxUSE_STD_IOSTREAM +WXDLLIMPEXP_BASE std::ostream& OutputCharBuffer(std::ostream&, const char* s); +WXDLLIMPEXP_BASE std::ostream& OutputWCharBuffer(std::ostream&, const wchar_t* ws); +#if defined(HAVE_WOSTREAM) +WXDLLIMPEXP_BASE std::wostream& OutputWCharBuffer(std::wostream&, const wchar_t* ws); +#endif // defined(HAVE_WOSTREAM) +#endif // wxUSE_STD_IOSTREAM + } // namespace wxPrivate +// Template used as CRTP base class for wxScopedCharTypeBuffer in order to +// define overloaded operator<<() for it. +// +// By default we don't define any operators, but we do define them for the +// usual char and wchar_t specializations below. +template +struct wxScopedCharTypeBufferStreamSupport +{ +}; + +// Suppress the warning about declaring a non-template friend because this is +// exactly what we want to do here. +wxGCC_ONLY_WARNING_SUPPRESS(non-template-friend) + +template +struct wxScopedCharTypeBufferStreamSupport +{ +#if wxUSE_STD_IOSTREAM + friend std::ostream& operator<<(std::ostream& oss, const Buffer& buf) + { + return wxPrivate::OutputCharBuffer(oss, buf.data()); + } +#endif // wxUSE_STD_IOSTREAM +}; + +template +struct wxScopedCharTypeBufferStreamSupport +{ +#if wxUSE_STD_IOSTREAM + friend std::ostream& operator<<(std::ostream& oss, const Buffer& buf) + { + return wxPrivate::OutputWCharBuffer(oss, buf.data()); + } +#if defined(HAVE_WOSTREAM) + friend std::wostream& operator<<(std::wostream& woss, const Buffer& buf) + { + return wxPrivate::OutputWCharBuffer(woss, buf.data()); + } +#endif // defined(HAVE_WOSTREAM) +#endif // wxUSE_STD_IOSTREAM +}; + +wxGCC_ONLY_WARNING_RESTORE(non-template-friend) + + // Reference-counted character buffer for storing string data. The buffer // is only valid for as long as the "parent" object that provided the data // is valid; see wxCharTypeBuffer for persistent variant. template class wxScopedCharTypeBuffer + : wxScopedCharTypeBufferStreamSupport> { public: typedef T CharType; @@ -368,6 +428,13 @@ public: wxCharBuffer(size_t len) : wxCharTypeBufferBase(len) {} wxCharBuffer(const wxCStrData& cstr); + +#if wxUSE_STD_IOSTREAM + // Define this to disambiguate between converting to the base class or to + // wxString when using operator<<() with the objects of this class. + friend WXDLLIMPEXP_BASE + std::ostream& operator<<(std::ostream& oss, const wxCharBuffer& buf); +#endif // wxUSE_STD_IOSTREAM }; class wxWCharBuffer : public wxCharTypeBuffer @@ -385,6 +452,16 @@ public: wxWCharBuffer(size_t len) : wxCharTypeBufferBase(len) {} wxWCharBuffer(const wxCStrData& cstr); + +#if wxUSE_STD_IOSTREAM + // See wxCharBuffer for why this is needed. + friend WXDLLIMPEXP_BASE + std::ostream& operator<<(std::ostream& oss, const wxWCharBuffer& buf); +#if defined(HAVE_WOSTREAM) + friend WXDLLIMPEXP_BASE + std::wostream& operator<<(std::wostream& woss, const wxWCharBuffer& buf); +#endif // defined(HAVE_WOSTREAM) +#endif // wxUSE_STD_IOSTREAM }; // wxCharTypeBuffer implicitly convertible to T*, for char and wchar_t, diff --git a/include/wx/string.h b/include/wx/string.h index 31affce6fe..094327d7c9 100644 --- a/include/wx/string.h +++ b/include/wx/string.h @@ -291,6 +291,13 @@ public: return p - cs.AsWChar(); } +#if wxUSE_STD_IOSTREAM + friend WXDLLIMPEXP_BASE std::ostream& operator<<(std::ostream&, const wxCStrData&); +#if defined(HAVE_WOSTREAM) + friend WXDLLIMPEXP_BASE std::wostream& operator<<(std::wostream&, const wxCStrData&); +#endif // defined(HAVE_WOSTREAM) +#endif // wxUSE_STD_IOSTREAM + private: // the wxString this object was returned for const wxString *m_str; @@ -3626,6 +3633,13 @@ public: wxString& operator+=(unsigned char ch) { return *this += wxUniChar(ch); } wxString& operator+=(wchar_t ch) { return *this += wxUniChar(ch); } +#if wxUSE_STD_IOSTREAM + friend WXDLLIMPEXP_BASE std::ostream& operator<<(std::ostream&, const wxString&); +#if defined(HAVE_WOSTREAM) + friend WXDLLIMPEXP_BASE std::wostream& operator<<(std::wostream&, const wxString&); +#endif // defined(HAVE_WOSTREAM) +#endif // wxUSE_STD_IOSTREAM + private: #if !wxUSE_UTF8_LOCALE_ONLY int DoPrintfWchar(const wxChar *format, ...); @@ -4158,27 +4172,6 @@ namespace std // Implementation only from here until the end of file // --------------------------------------------------------------------------- -#if wxUSE_STD_IOSTREAM - -#include "wx/iosfwrap.h" - -WXDLLIMPEXP_BASE std::ostream& operator<<(std::ostream&, const wxString&); -WXDLLIMPEXP_BASE std::ostream& operator<<(std::ostream&, const wxCStrData&); -#ifndef wxNO_IMPLICIT_WXSTRING_ENCODING -WXDLLIMPEXP_BASE std::ostream& operator<<(std::ostream&, const wxScopedCharBuffer&); -#endif // wxNO_IMPLICIT_WXSTRING_ENCODING -WXDLLIMPEXP_BASE std::ostream& operator<<(std::ostream&, const wxScopedWCharBuffer&); - -#if defined(HAVE_WOSTREAM) - -WXDLLIMPEXP_BASE std::wostream& operator<<(std::wostream&, const wxString&); -WXDLLIMPEXP_BASE std::wostream& operator<<(std::wostream&, const wxCStrData&); -WXDLLIMPEXP_BASE std::wostream& operator<<(std::wostream&, const wxScopedWCharBuffer&); - -#endif // defined(HAVE_WOSTREAM) - -#endif // wxUSE_STD_IOSTREAM - // --------------------------------------------------------------------------- // wxCStrData implementation // --------------------------------------------------------------------------- diff --git a/src/common/string.cpp b/src/common/string.cpp index 9014dd472e..c530ffc053 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -169,17 +169,29 @@ std::ostream& operator<<(std::ostream& os, const wxString& str) return os << str.c_str(); } -std::ostream& operator<<(std::ostream& os, const wxScopedCharBuffer& str) +std::ostream& +wxPrivate::OutputCharBuffer(std::ostream& os, const char* str) +{ + return os << str; +} + +std::ostream& operator<<(std::ostream& os, const wxCharBuffer& str) { return os << str.data(); } -std::ostream& operator<<(std::ostream& os, const wxScopedWCharBuffer& str) +std::ostream& +wxPrivate::OutputWCharBuffer(std::ostream& os, const wchar_t* wstr) { // There is no way to write wide character data to std::ostream directly, // but we need to define this operator for compatibility, as we provided it // since basically always, even if it never worked correctly before. So do // the only reasonable thing and output it as UTF-8. + return os << wxConvWhateverWorks.cWC2MB(wstr); +} + +std::ostream& operator<<(std::ostream& os, const wxWCharBuffer& str) +{ return os << wxConvWhateverWorks.cWC2MB(str.data()); } @@ -195,7 +207,13 @@ std::wostream& operator<<(std::wostream& wos, const wxCStrData& str) return wos << str.AsWChar(); } -std::wostream& operator<<(std::wostream& wos, const wxScopedWCharBuffer& str) +std::wostream& +wxPrivate::OutputWCharBuffer(std::wostream& wos, const wchar_t* wstr) +{ + return wos << wstr; +} + +std::wostream& operator<<(std::wostream& wos, const wxWCharBuffer& str) { return wos << str.data(); } From cfdfd14c59df06bd3b98e2f27e3deeac0212492e Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 5 Jan 2024 03:03:55 +0100 Subject: [PATCH 238/257] Improve frame size in the listctrl sample Make it bigger on high DPI displays and smaller on normal ones. --- samples/listctrl/listtest.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/samples/listctrl/listtest.cpp b/samples/listctrl/listtest.cpp index 9f1af0b595..e08687d867 100644 --- a/samples/listctrl/listtest.cpp +++ b/samples/listctrl/listtest.cpp @@ -170,7 +170,7 @@ wxEND_EVENT_TABLE() // My frame constructor MyFrame::MyFrame(const wxString& title) - : wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition, wxSize(600, 500)) + : wxFrame(nullptr, wxID_ANY, title) { m_listCtrl = nullptr; m_logWindow = nullptr; @@ -293,6 +293,9 @@ MyFrame::MyFrame(const wxString& title) RecreateList(wxLC_REPORT | wxLC_SINGLE_SEL); + // Make the list control big enough to show its initial contents. + m_listCtrl->SetInitialSize(FromDIP(wxSize(600, 300))); + #ifdef __WXMSW__ // this is useful to know specially when debugging :) wxLogMessage("Your version of comctl32.dll is: %d", From d36fd5822d8128f43c3ae87403c8988bc173293d Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 7 Jan 2024 00:42:44 +0100 Subject: [PATCH 239/257] Add MSVS 2022 solutions files for building tests They're almost identical to MSVS 2019 ones but still convenient to have. --- tests/test_gui_vc17.sln | 273 ++++++++++++++++++++++++++++++++++++++++ tests/test_vc17.sln | 99 +++++++++++++++ 2 files changed, 372 insertions(+) create mode 100644 tests/test_gui_vc17.sln create mode 100644 tests/test_vc17.sln diff --git a/tests/test_gui_vc17.sln b/tests/test_gui_vc17.sln new file mode 100644 index 0000000000..5abd887abe --- /dev/null +++ b/tests/test_gui_vc17.sln @@ -0,0 +1,273 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31919.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_gui", "test_gui.vcxproj", "{9BB295D9-A6AA-510D-AA0D-9375B5D91025}" + ProjectSection(ProjectDependencies) = postProject + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6} = {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6} + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E} = {A8E8442A-078A-5FC5-B495-8D71BA77EE6E} + {7FB0902D-8579-5DCE-B883-DAF66A885005} = {7FB0902D-8579-5DCE-B883-DAF66A885005} + {A16D3832-0F42-57CE-8F48-50E06649ADE8} = {A16D3832-0F42-57CE-8F48-50E06649ADE8} + {23E1C437-A951-5943-8639-A17F3CF2E606} = {23E1C437-A951-5943-8639-A17F3CF2E606} + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63} = {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63} + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D} = {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D} + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1} = {3FCC50C2-81E9-5DB2-B8D8-2129427568B1} + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} = {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75} + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550} = {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550} + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00} = {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00} + {33CC42F9-7756-5587-863C-8D4461B7C5DD} = {33CC42F9-7756-5587-863C-8D4461B7C5DD} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "..\build\msw\wx_base.vcxproj", "{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "core", "..\build\msw\wx_core.vcxproj", "{6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "richtext", "..\build\msw\wx_richtext.vcxproj", "{7FB0902D-8579-5DCE-B883-DAF66A885005}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "media", "..\build\msw\wx_media.vcxproj", "{8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "html", "..\build\msw\wx_html.vcxproj", "{33CC42F9-7756-5587-863C-8D4461B7C5DD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net", "..\build\msw\wx_net.vcxproj", "{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml", "..\build\msw\wx_xml.vcxproj", "{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrc", "..\build\msw\wx_xrc.vcxproj", "{09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "webview", "..\build\msw\wx_webview.vcxproj", "{A8E8442A-078A-5FC5-B495-8D71BA77EE6E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "aui", "..\build\msw\wx_aui.vcxproj", "{A16D3832-0F42-57CE-8F48-50E06649ADE8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "propgrid", "..\build\msw\wx_propgrid.vcxproj", "{97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stc", "..\build\msw\wx_stc.vcxproj", "{23E1C437-A951-5943-8639-A17F3CF2E606}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + DLL Debug|Win32 = DLL Debug|Win32 + DLL Debug|x64 = DLL Debug|x64 + DLL Release|Win32 = DLL Release|Win32 + DLL Release|x64 = DLL Release|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.Debug|Win32.ActiveCfg = Debug|Win32 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.Debug|Win32.Build.0 = Debug|Win32 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.Debug|x64.ActiveCfg = Debug|x64 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.Debug|x64.Build.0 = Debug|x64 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.DLL Release|x64.Build.0 = DLL Release|x64 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.Release|Win32.ActiveCfg = Release|Win32 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.Release|Win32.Build.0 = Release|Win32 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.Release|x64.ActiveCfg = Release|x64 + {9BB295D9-A6AA-510D-AA0D-9375B5D91025}.Release|x64.Build.0 = Release|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.ActiveCfg = Debug|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.Build.0 = Debug|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.ActiveCfg = Debug|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.Build.0 = Debug|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Release|x64.Build.0 = DLL Release|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|Win32.ActiveCfg = Release|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|Win32.Build.0 = Release|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.ActiveCfg = Release|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.Build.0 = Release|x64 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|Win32.ActiveCfg = Debug|Win32 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|Win32.Build.0 = Debug|Win32 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|x64.ActiveCfg = Debug|x64 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Debug|x64.Build.0 = Debug|x64 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.DLL Release|x64.Build.0 = DLL Release|x64 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|Win32.ActiveCfg = Release|Win32 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|Win32.Build.0 = Release|Win32 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|x64.ActiveCfg = Release|x64 + {6744DAD8-9C70-574A-BFF2-9F8DDDB24A75}.Release|x64.Build.0 = Release|x64 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.Debug|Win32.ActiveCfg = Debug|Win32 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.Debug|Win32.Build.0 = Debug|Win32 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.Debug|x64.ActiveCfg = Debug|x64 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.Debug|x64.Build.0 = Debug|x64 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.DLL Release|x64.Build.0 = DLL Release|x64 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.Release|Win32.ActiveCfg = Release|Win32 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.Release|Win32.Build.0 = Release|Win32 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.Release|x64.ActiveCfg = Release|x64 + {7FB0902D-8579-5DCE-B883-DAF66A885005}.Release|x64.Build.0 = Release|x64 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Debug|Win32.ActiveCfg = Debug|Win32 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Debug|Win32.Build.0 = Debug|Win32 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Debug|x64.ActiveCfg = Debug|x64 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Debug|x64.Build.0 = Debug|x64 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.DLL Release|x64.Build.0 = DLL Release|x64 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Release|Win32.ActiveCfg = Release|Win32 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Release|Win32.Build.0 = Release|Win32 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Release|x64.ActiveCfg = Release|x64 + {8BD8F8D9-4275-5B42-A8F4-F1DB2970A550}.Release|x64.Build.0 = Release|x64 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.Debug|Win32.ActiveCfg = Debug|Win32 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.Debug|Win32.Build.0 = Debug|Win32 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.Debug|x64.ActiveCfg = Debug|x64 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.Debug|x64.Build.0 = Debug|x64 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.DLL Release|x64.Build.0 = DLL Release|x64 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.Release|Win32.ActiveCfg = Release|Win32 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.Release|Win32.Build.0 = Release|Win32 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.Release|x64.ActiveCfg = Release|x64 + {33CC42F9-7756-5587-863C-8D4461B7C5DD}.Release|x64.Build.0 = Release|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug|Win32.ActiveCfg = Debug|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug|Win32.Build.0 = Debug|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug|x64.ActiveCfg = Debug|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug|x64.Build.0 = Debug|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Release|x64.Build.0 = DLL Release|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release|Win32.ActiveCfg = Release|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release|Win32.Build.0 = Release|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release|x64.ActiveCfg = Release|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release|x64.Build.0 = Release|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug|Win32.ActiveCfg = Debug|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug|Win32.Build.0 = Debug|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug|x64.ActiveCfg = Debug|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug|x64.Build.0 = Debug|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Release|x64.Build.0 = DLL Release|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release|Win32.ActiveCfg = Release|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release|Win32.Build.0 = Release|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release|x64.ActiveCfg = Release|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release|x64.Build.0 = Release|x64 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Debug|Win32.ActiveCfg = Debug|Win32 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Debug|Win32.Build.0 = Debug|Win32 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Debug|x64.ActiveCfg = Debug|x64 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Debug|x64.Build.0 = Debug|x64 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.DLL Release|x64.Build.0 = DLL Release|x64 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Release|Win32.ActiveCfg = Release|Win32 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Release|Win32.Build.0 = Release|Win32 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Release|x64.ActiveCfg = Release|x64 + {09F2F96A-1CC6-5E43-AF1D-956EC2A4888D}.Release|x64.Build.0 = Release|x64 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Debug|Win32.ActiveCfg = Debug|Win32 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Debug|Win32.Build.0 = Debug|Win32 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Debug|x64.ActiveCfg = Debug|x64 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Debug|x64.Build.0 = Debug|x64 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.DLL Release|x64.Build.0 = DLL Release|x64 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Release|Win32.ActiveCfg = Release|Win32 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Release|Win32.Build.0 = Release|Win32 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Release|x64.ActiveCfg = Release|x64 + {A8E8442A-078A-5FC5-B495-8D71BA77EE6E}.Release|x64.Build.0 = Release|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug|Win32.ActiveCfg = Debug|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug|Win32.Build.0 = Debug|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug|x64.ActiveCfg = Debug|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Debug|x64.Build.0 = Debug|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.DLL Release|x64.Build.0 = DLL Release|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release|Win32.ActiveCfg = Release|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release|Win32.Build.0 = Release|Win32 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release|x64.ActiveCfg = Release|x64 + {A16D3832-0F42-57CE-8F48-50E06649ADE8}.Release|x64.Build.0 = Release|x64 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Debug|Win32.ActiveCfg = Debug|Win32 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Debug|Win32.Build.0 = Debug|Win32 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Debug|x64.ActiveCfg = Debug|x64 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Debug|x64.Build.0 = Debug|x64 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.DLL Release|x64.Build.0 = DLL Release|x64 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Release|Win32.ActiveCfg = Release|Win32 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Release|Win32.Build.0 = Release|Win32 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Release|x64.ActiveCfg = Release|x64 + {97FDAB45-9C58-5BC5-A2F4-EE42739EBC63}.Release|x64.Build.0 = Release|x64 + {23E1C437-A951-5943-8639-A17F3CF2E606}.Debug|Win32.ActiveCfg = Debug|Win32 + {23E1C437-A951-5943-8639-A17F3CF2E606}.Debug|Win32.Build.0 = Debug|Win32 + {23E1C437-A951-5943-8639-A17F3CF2E606}.Debug|x64.ActiveCfg = Debug|x64 + {23E1C437-A951-5943-8639-A17F3CF2E606}.Debug|x64.Build.0 = Debug|x64 + {23E1C437-A951-5943-8639-A17F3CF2E606}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {23E1C437-A951-5943-8639-A17F3CF2E606}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {23E1C437-A951-5943-8639-A17F3CF2E606}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {23E1C437-A951-5943-8639-A17F3CF2E606}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {23E1C437-A951-5943-8639-A17F3CF2E606}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {23E1C437-A951-5943-8639-A17F3CF2E606}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {23E1C437-A951-5943-8639-A17F3CF2E606}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {23E1C437-A951-5943-8639-A17F3CF2E606}.DLL Release|x64.Build.0 = DLL Release|x64 + {23E1C437-A951-5943-8639-A17F3CF2E606}.Release|Win32.ActiveCfg = Release|Win32 + {23E1C437-A951-5943-8639-A17F3CF2E606}.Release|Win32.Build.0 = Release|Win32 + {23E1C437-A951-5943-8639-A17F3CF2E606}.Release|x64.ActiveCfg = Release|x64 + {23E1C437-A951-5943-8639-A17F3CF2E606}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {69C787B9-5194-4D53-A6B2-8496DB9414FA} + EndGlobalSection +EndGlobal diff --git a/tests/test_vc17.sln b/tests/test_vc17.sln new file mode 100644 index 0000000000..fb7bfd6005 --- /dev/null +++ b/tests/test_vc17.sln @@ -0,0 +1,99 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31919.166 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{2F45723C-ED6B-5F60-8BFF-6B3609464A7B}" + ProjectSection(ProjectDependencies) = postProject + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6} = {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6} + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1} = {3FCC50C2-81E9-5DB2-B8D8-2129427568B1} + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00} = {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "..\build\msw\wx_base.vcxproj", "{3FCC50C2-81E9-5DB2-B8D8-2129427568B1}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "net", "..\build\msw\wx_net.vcxproj", "{69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xml", "..\build\msw\wx_xml.vcxproj", "{3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + DLL Debug|Win32 = DLL Debug|Win32 + DLL Debug|x64 = DLL Debug|x64 + DLL Release|Win32 = DLL Release|Win32 + DLL Release|x64 = DLL Release|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.Debug|Win32.ActiveCfg = Debug|Win32 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.Debug|Win32.Build.0 = Debug|Win32 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.Debug|x64.ActiveCfg = Debug|x64 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.Debug|x64.Build.0 = Debug|x64 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.DLL Release|x64.Build.0 = DLL Release|x64 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.Release|Win32.ActiveCfg = Release|Win32 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.Release|Win32.Build.0 = Release|Win32 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.Release|x64.ActiveCfg = Release|x64 + {2F45723C-ED6B-5F60-8BFF-6B3609464A7B}.Release|x64.Build.0 = Release|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.ActiveCfg = Debug|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|Win32.Build.0 = Debug|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.ActiveCfg = Debug|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Debug|x64.Build.0 = Debug|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.DLL Release|x64.Build.0 = DLL Release|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|Win32.ActiveCfg = Release|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|Win32.Build.0 = Release|Win32 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.ActiveCfg = Release|x64 + {3FCC50C2-81E9-5DB2-B8D8-2129427568B1}.Release|x64.Build.0 = Release|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug|Win32.ActiveCfg = Debug|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug|Win32.Build.0 = Debug|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug|x64.ActiveCfg = Debug|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Debug|x64.Build.0 = Debug|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.DLL Release|x64.Build.0 = DLL Release|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release|Win32.ActiveCfg = Release|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release|Win32.Build.0 = Release|Win32 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release|x64.ActiveCfg = Release|x64 + {69F2EDE4-7D21-5738-9BC0-F66F61C9AE00}.Release|x64.Build.0 = Release|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug|Win32.ActiveCfg = Debug|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug|Win32.Build.0 = Debug|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug|x64.ActiveCfg = Debug|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Debug|x64.Build.0 = Debug|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Release|Win32.Build.0 = DLL Release|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Release|x64.ActiveCfg = DLL Release|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.DLL Release|x64.Build.0 = DLL Release|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release|Win32.ActiveCfg = Release|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release|Win32.Build.0 = Release|Win32 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release|x64.ActiveCfg = Release|x64 + {3E6DCA27-5FA3-53EC-BBD6-2D42294B7AE6}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal From 30dd7e909549121642022bfa93e970131a0481b9 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 7 Jan 2024 22:12:28 +0100 Subject: [PATCH 240/257] Add wxLogBuffer::Clear() This can be used to prevent the log buffer contents from being flushed when replacing it with another logger, which is typically undesirable. --- include/wx/log.h | 4 ++++ interface/wx/log.h | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/include/wx/log.h b/include/wx/log.h index 9dfd9117aa..8e1e01b25a 100644 --- a/include/wx/log.h +++ b/include/wx/log.h @@ -665,6 +665,10 @@ public: // get the string contents with all messages logged const wxString& GetBuffer() const { return m_str; } + // clear all the messages, this, in particular, prevents them from being + // flushed + void Clear() { m_str.clear(); } + // show the buffer contents to the user in the best possible way (this uses // wxMessageOutputMessageBox) and clear it virtual void Flush() override; diff --git a/interface/wx/log.h b/interface/wx/log.h index af5cb85d6e..087f31b665 100644 --- a/interface/wx/log.h +++ b/interface/wx/log.h @@ -900,6 +900,18 @@ public: */ wxLogBuffer(); + /** + Clear all the messages in the buffer. + + This can be done to prevent them from being flushed by the next call to + Flush(), which happens implicitly if this logger ceases to be the + active logger after a call to wxLog::SetActiveTarget() with a different + log target. + + @since 3.3.0 + */ + void Clear(); + /** Shows all the messages collected so far to the user (using a message box in the GUI applications or by printing them out to the console in text mode) and From 2566a1abf52b65a4a0f3a0eb951dbbf57169307a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 7 Jan 2024 22:31:52 +0100 Subject: [PATCH 241/257] Add wxLogFormatterNone This trivial class allows to easily disable all log formatting, including time stamping and level-dependent prefixes. --- include/wx/log.h | 13 +++++++++++++ interface/wx/log.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/include/wx/log.h b/include/wx/log.h index 8e1e01b25a..724d80aae5 100644 --- a/include/wx/log.h +++ b/include/wx/log.h @@ -341,6 +341,19 @@ protected: #endif // WXWIN_COMPATIBILITY_3_0 }; +// Special kind of trivial formatter which simply uses the message unchanged. +class wxLogFormatterNone : public wxLogFormatter +{ +public: + wxLogFormatterNone() = default; + + virtual wxString Format(wxLogLevel WXUNUSED(level), + const wxString& msg, + const wxLogRecordInfo& WXUNUSED(info)) const override + { + return msg; + } +}; // ---------------------------------------------------------------------------- // derive from this class to redirect (or suppress, or ...) log messages diff --git a/interface/wx/log.h b/interface/wx/log.h index 087f31b665..e65691c3a3 100644 --- a/interface/wx/log.h +++ b/interface/wx/log.h @@ -115,6 +115,9 @@ public: [7872] d:\testApp\src\testApp.cpp(85) : *** Application started *** @endverbatim + See wxLogFormatterNone for a trivial version of this class not doing any + formatting, + @library{wxbase} @category{logging} @@ -195,6 +198,31 @@ protected: }; +/** + Specialized formatter not formatting the messages at all. + + This class can be used to make wxLog log just the messages themselves, + without any time stamps or prefixes indicating their severity. + + Example of using it: + + @code + wxLog* logger = wxLog::GetActiveTarget(); + delete logger->SetFormatter(new wxLogFormatterNone{}); + + // Log messages won't have time stamps or "Error:", "Warning:" etc + // prefixes any more. + @endcode + + @since 3.3.0 +*/ +class wxLogFormatterNone : public wxLogFormatter +{ +public: + /// Trivial default constructor. + wxLogFormatterNone(); +}; + /** @class wxLog From 4fc22812864c3efdd7cb882be838f88307a6594b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 7 Jan 2024 22:39:45 +0100 Subject: [PATCH 242/257] Add wxLogCollector This class is more convenient than wxLogBuffer that it uses and can be used to collect all the logged messages in a string during its lifetime. --- include/wx/log.h | 35 ++++++++++++++++++++++++++ interface/wx/log.h | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) diff --git a/include/wx/log.h b/include/wx/log.h index 724d80aae5..83e08f7e10 100644 --- a/include/wx/log.h +++ b/include/wx/log.h @@ -765,6 +765,41 @@ private: bool m_flagOld; // the previous value of the wxLog::ms_doLog }; +// ---------------------------------------------------------------------------- +// Collect all logged messages into a (multiline) string. +// ---------------------------------------------------------------------------- + +// This class is supposed to be used as a local variable and collects, without +// showing them, all the messages logged during its lifetime. +class wxLogCollector +{ +public: + wxLogCollector() + : m_logOrig{wxLog::SetActiveTarget(&m_logBuf)} + { + delete m_logBuf.SetFormatter(new wxLogFormatterNone{}); + } + + ~wxLogCollector() + { + // Don't flush the messages in the buffer. + m_logBuf.Clear(); + + wxLog::SetActiveTarget(m_logOrig); + } + + const wxString& GetMessages() const + { + return m_logBuf.GetBuffer(); + } + +private: + wxLogBuffer m_logBuf; + wxLog* const m_logOrig; + + wxDECLARE_NO_COPY_CLASS(wxLogCollector); +}; + // ---------------------------------------------------------------------------- // chaining log target: installs itself as a log target and passes all // messages to the real log target given to it in the ctor but also forwards diff --git a/interface/wx/log.h b/interface/wx/log.h index e65691c3a3..a8fc5125f7 100644 --- a/interface/wx/log.h +++ b/interface/wx/log.h @@ -957,6 +957,65 @@ public: }; +/** + @class wxLogCollector + + Allows to collect all log messages into a string instead of showing them. + + This class is supposed to be used as a local variable and collects all the + messages logged during its lifetime instead of showing them as usual, e.g. + + @code + void Foo() + { + wxLogCollector collectLogs; + + // Call some function that can log error messages, e.g. try to create a + // new directory. Without wxLogCollector a failure here would show + // errors to the user. + if ( !wxFileName::Mkdir("/some/path", wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL) ) + { + // Instead, we can report them here as we see fit, e.g. write them + // to a log file or process them in some other way. + wxFprintf(logFile, "Creating directory failed: %s", + collectLogs.GetMessages()); + } + } + @endcode + + Note that because this class uses wxLog::SetActiveTarget() to temporarily + switch the active log target to wxLogBuffer, you need to ensure that the + log target doesn't change while it is alive (in the simplest case by just + avoiding to change it at all). + + @since 3.3.0 +*/ +class wxLogCollector +{ +public: + /** + Constructor overrides active log target to collect messages. + */ + wxLogCollector(); + + /** + Get all the collected messages. + + The returned string may be empty but if it isn't, it contains the + trailing new line (and may also contain more new lines inside it if + multiple messages were logged). + + Note that the messages here contain just the messages, without any time + stamps or log level prefixes. + */ + const wxString& GetMessages() const; + + /** + Destructor restores the previously active log target. + */ + ~wxLogCollector(); +}; + /** @class wxLogNull @@ -1005,6 +1064,8 @@ public: This class is thread-safe and can be used from both the main and the backgrounds threads. + @see wxLogCollector + @library{wxbase} @category{logging} */ From e717ac5a86d025112c4c0081817aa3285812b9f5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 7 Jan 2024 22:44:09 +0100 Subject: [PATCH 243/257] Return more detailed errors from wxFileConfig::MigrateLocalFile() Add the errors logged by various file functions called from this function to the returned error message instead of letting wxLog show them as usual because it may be necessary to show an interactive message box, asking the user about the action to take, if migrating the existing file failed, and it is poor UI to show both the message box from wxLog and this message box at the same time -- so avoid showing the former. --- src/common/fileconf.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index 17e6b6469e..7f91235db5 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -360,6 +360,36 @@ wxFileConfig::MigrateLocalFile(const wxString& name, int newStyle, int oldStyle) wxString currentPath = res.oldPath; + class AppendLogToError + { + public: + explicit AppendLogToError(MigrationResult& res) + : m_res(res) + { + } + + ~AppendLogToError() + { + if ( !m_res.error.empty() ) + { + wxString msg = m_logCollect.GetMessages(); + if ( !msg.empty() ) + { + // Normally the messages are separated with new lines, but + // we don't need the trailing one after the last one. + if ( msg.Last() == '\n' ) + msg.RemoveLast(); + m_res.error << _(" due to the following error:\n") << msg; + } + } + } + + private: + MigrationResult& m_res; + + wxLogCollector m_logCollect; + } appendLogToError{res}; + const auto newDir = newPath.GetPath(); if ( !wxFileName::DirExists(newDir) ) { From 6586afb0a58b1c3b59ca6efa8613f4e0b52a8c7a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 8 Jan 2024 00:43:26 +0100 Subject: [PATCH 244/257] Use XDG-compliant location by default in wxFileConfig Still use the traditional dot file if it already exists, but prefer using the new location otherwise, i.e. for the new program installation. Add wxCONFIG_USE_HOME to allow forcing the use of the old location if really necessary. Also use the new style as default "old style" of MigrateLocalFile() so that calling it even when using XDG layout in wxStandardPaths still works as expected. --- docs/changes.txt | 6 ++++++ include/wx/confbase.h | 3 ++- include/wx/fileconf.h | 4 +++- interface/wx/config.h | 24 ++++++++++++++++++++++-- interface/wx/fileconf.h | 16 +++++++++------- src/common/fileconf.cpp | 26 ++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 11 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index e20e6429ac..e813684a3a 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -31,6 +31,12 @@ Changes in behaviour not resulting in compilation errors wxGLAttributes::Samplers(1).SampleBuffers(4) explicitly if you need to keep using the same attributes that were previously used by default. +- Default location of file used by wxFileConfig under Unix has changed to + XDG-compliant ~/.config/appname.conf instead of ~/.appname but note that + any existing files at the old location will still continue to be used. + See wxCONFIG_USE_XDG and wxCONFIG_USE_HOME for how to customize this + behaviour. You may also find wxFileConfig::MigrateLocalFile() useful. + - As first mentioned in 3.0 release notes, the value of wxTHREAD_WAIT_DEFAULT, used by wxThread::Delete() and Wait() by default, has changed from wxTHREAD_WAIT_YIELD to wxTHREAD_WAIT_BLOCK for safety and consistency. diff --git a/include/wx/confbase.h b/include/wx/confbase.h index bc00ec1413..34e250ce90 100644 --- a/include/wx/confbase.h +++ b/include/wx/confbase.h @@ -63,7 +63,8 @@ enum wxCONFIG_USE_RELATIVE_PATH = 4, wxCONFIG_USE_NO_ESCAPE_CHARACTERS = 8, wxCONFIG_USE_SUBDIR = 16, - wxCONFIG_USE_XDG = 32 + wxCONFIG_USE_XDG = 32, + wxCONFIG_USE_HOME = 64 }; // ---------------------------------------------------------------------------- diff --git a/include/wx/fileconf.h b/include/wx/fileconf.h index 4229820cf8..31971df83e 100644 --- a/include/wx/fileconf.h +++ b/include/wx/fileconf.h @@ -137,7 +137,9 @@ public: wxString error; }; static MigrationResult - MigrateLocalFile(const wxString& name, int newStyle, int oldStyle = 0); + MigrateLocalFile(const wxString& name, + int newStyle, + int oldStyle = wxCONFIG_USE_HOME); // ctor & dtor // New constructor: one size fits all. Specify wxCONFIG_USE_LOCAL_FILE or diff --git a/interface/wx/config.h b/interface/wx/config.h index 3be4368c66..f0169b693e 100644 --- a/interface/wx/config.h +++ b/interface/wx/config.h @@ -28,7 +28,7 @@ enum wxCONFIG_USE_SUBDIR = 16, /** - Use XDG-compliant file location on Unix systems. + Always use XDG-compliant file location on Unix systems. If wxCONFIG_USE_SUBDIR is not specified, using this flag has the same effect as calling wxStandardPaths::SetFileLayout() with @@ -38,9 +38,29 @@ enum In combination with wxCONFIG_USE_SUBDIR, this flag changes the default configuration file location to ~/.config/appname/appname.conf`. + If neither this flag nor wxCONFIG_USE_HOME is specified, XDG-compliant + configuration file path will be used by default, but if there is an + existing file in the home directory, then it will continue to be used + instead. + @since 3.3.0 */ - wxCONFIG_USE_XDG = 32 + wxCONFIG_USE_XDG = 32, + + /** + Use home directory for the local file location on Unix systems. + + Using this flag is not recommended, it exists only for compatibility + with the previous wxWidgets versions which created configuration files + in the home directory (i.e. `~/.appname`) by default. + + Note that any already existing files in the home directory will still + be used, even if this file is not specified, unless wxCONFIG_USE_XDG is + used. + + @since 3.3.0 + */ + wxCONFIG_USE_HOME = 64 }; diff --git a/interface/wx/fileconf.h b/interface/wx/fileconf.h index 05f3c14b21..95ae264a50 100644 --- a/interface/wx/fileconf.h +++ b/interface/wx/fileconf.h @@ -90,8 +90,8 @@ public: parameter in the constructor. @a style has the same meaning as in @ref wxConfigBase::wxConfigBase "wxConfig constructor" - and can contain any combination of styles but only wxCONFIG_USE_SUBDIR - and wxCONFIG_USE_XDG are really used by this function. + and can contain any combination of styles but only wxCONFIG_USE_SUBDIR, + wxCONFIG_USE_XDG and wxCONFIG_USE_HOME are really used by this function. Notice that this function cannot be used if @a basename is already a full path name. */ @@ -146,9 +146,8 @@ public: } } - // Note that this must be done after calling MigrateLocalFile(), - // otherwise the old style would use XDG layout already and the actual - // file at non-XDG-compliant location wouldn't be migrated. + // Prefer doing it only after successfully calling MigrateLocalFile(), + // otherwise, i.e. if it failed, the old config file wouldn't be used. wxStandardPaths::Get().SetFileLayout(wxStandardPaths::FileLayout_XDG); @endcode @@ -157,12 +156,15 @@ public: program, typically including ::wxCONFIG_USE_XDG and possibly also including ::wxCONFIG_USE_SUBDIR. @param oldStyle Style which was used by the previous versions of the - program, possibly including ::wxCONFIG_USE_SUBDIR. + program, possibly including ::wxCONFIG_USE_SUBDIR and typically + including ::wxCONFIG_USE_HOME. @since 3.3.0 */ static MigrationResult - MigrateLocalFile(const wxString& name, int newStyle, int oldStyle = 0); + MigrateLocalFile(const wxString& name, + int newStyle, + int oldStyle = wxCONFIG_USE_HOME); /** Saves all config data to the given stream, returns @true if data was saved diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index 17e6b6469e..097bd551eb 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -261,6 +261,18 @@ wxString wxFileConfig::GetLocalDir(int style) return dir; } + if ( style & wxCONFIG_USE_HOME ) + { + // When traditional layout is requested, don't use wxStandardPaths as + // it could be using XDG layout. + wxString dir = wxGetHomeDir(); + + if ( style & wxCONFIG_USE_HOME ) + dir = stdp.AppendAppInfo(dir); + + return dir; + } + // Normally we'd like to use GetUserConfigDir() and just append app info // subdirectories to it, but we can't do it for compatibility reasons: // there are existing configuration files in the locations returned by @@ -469,8 +481,22 @@ wxFileConfig::wxFileConfig(const wxString& appName, const wxString& vendorName, { // Make up names for files if empty if ( !m_fnLocalFile.IsOk() && (style & wxCONFIG_USE_LOCAL_FILE) ) + { m_fnLocalFile = GetLocalFile(GetAppName(), style); + // If none of the styles explicitly selecting the location to use is + // specified, default to XDG unless the file already exists in the + // traditional location in the home directory: + if ( !(style & (wxCONFIG_USE_XDG | wxCONFIG_USE_HOME)) ) + { + if ( !m_fnLocalFile.FileExists() ) + { + style |= wxCONFIG_USE_XDG; + m_fnLocalFile = GetLocalFile(GetAppName(), style); + } + } + } + if ( !m_fnGlobalFile.IsOk() && (style & wxCONFIG_USE_GLOBAL_FILE) ) m_fnGlobalFile = GetGlobalFile(GetAppName()); From d7b9548c19c3f1d1a243d4afbaeb0b3f7bba6aa4 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Mon, 8 Jan 2024 02:02:18 +0100 Subject: [PATCH 245/257] Create output directory in wxFileConfig if it doesn't exist This seems like the most sensible thing to do. Alternative would be to not use XDG directories if ~/.config doesn't exist yet, but this doesn't seem right, especially if wxCONFIG_USE_XDG is explicitly specified. --- src/common/fileconf.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/common/fileconf.cpp b/src/common/fileconf.cpp index 097bd551eb..2f2a2d182a 100644 --- a/src/common/fileconf.cpp +++ b/src/common/fileconf.cpp @@ -1108,6 +1108,21 @@ bool wxFileConfig::Flush(bool /* bCurrentOnly */) if ( !IsDirty() || !m_fnLocalFile.GetFullPath() ) return true; + // Create the directory containing the file if it doesn't exist. Although we + // don't always use XDG, it seems sensible to follow the XDG specification + // and create it with permissions 700 if it doesn't exist. + const wxString& outPath = m_fnLocalFile.GetPath(); + if ( !wxFileName::DirExists(outPath) ) + { + if ( !wxFileName::Mkdir(outPath, + wxS_IRUSR | wxS_IWUSR | wxS_IXUSR, + wxPATH_MKDIR_FULL) ) + { + wxLogWarning(_("Failed to create configuration file directory.")); + return false; + } + } + // set the umask if needed wxCHANGE_UMASK(m_umask); From e2cc16ef9c45bdc64d42e4fef4dda46a3077cb35 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Jan 2024 02:38:43 +0100 Subject: [PATCH 246/257] Fix test suite on Linux/s390x and maybe other architectures We can't rely on file /sys/power/state always existing, so just skip the test (with a warning) instead of failing it if it does not exist, as is the case at least under s390x and seemingly other non-desktop platforms. Closes #24197. Co-authored-by: Cliff Zhao --- tests/file/filetest.cpp | 7 ++++++- tests/filename/filenametest.cpp | 6 ++++++ tests/textfile/textfiletest.cpp | 8 +++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/file/filetest.cpp b/tests/file/filetest.cpp index c2483b9afe..88b3a895ac 100644 --- a/tests/file/filetest.cpp +++ b/tests/file/filetest.cpp @@ -150,8 +150,13 @@ TEST_CASE("wxFile::Special", "[file][linux][special-file]") const long pageSize = sysconf(_SC_PAGESIZE); wxFile fileSys("/sys/power/state"); + if ( !fileSys.IsOpened() ) + { + WARN("/sys/power/state can't be opened, skipping test"); + return; + } + CHECK( fileSys.Length() == pageSize ); - CHECK( fileSys.IsOpened() ); CHECK( fileSys.ReadAll(&s) ); CHECK( !s.empty() ); CHECK( s.length() < static_cast(pageSize) ); diff --git a/tests/filename/filenametest.cpp b/tests/filename/filenametest.cpp index bee7bb10b9..01bbc9a77c 100644 --- a/tests/filename/filenametest.cpp +++ b/tests/filename/filenametest.cpp @@ -1040,6 +1040,12 @@ TEST_CASE("wxFileName::GetSizeSpecial", "[filename][linux][special-file]") INFO( "size of /proc/kcore=" << size ); CHECK( size > 0 ); + if ( !wxFile::Exists("/sys/power/state") ) + { + WARN("/sys/power/state doesn't exist, skipping test"); + return; + } + // All files in /sys are one page in size, irrespectively of the size of // their actual contents. CHECK( wxFileName::GetSize("/sys/power/state") == sysconf(_SC_PAGESIZE) ); diff --git a/tests/textfile/textfiletest.cpp b/tests/textfile/textfiletest.cpp index 8c29aab496..646d6818c9 100644 --- a/tests/textfile/textfiletest.cpp +++ b/tests/textfile/textfiletest.cpp @@ -336,12 +336,18 @@ TEST_CASE("wxTextFile::Special", "[textfile][linux][special-file]") SECTION("/proc") { wxTextFile f; - CHECK( f.Open("/proc/cpuinfo") ); + REQUIRE( f.Open("/proc/cpuinfo") ); CHECK( f.GetLineCount() > 1 ); } SECTION("/sys") { + if ( wxFile::Exists("/sys/power/state") ) + { + WARN("/sys/power/state doesn't exist, skipping test"); + return; + } + wxTextFile f; CHECK( f.Open("/sys/power/state") ); REQUIRE( f.GetLineCount() == 1 ); From 9cc5e5d276205d48e016d2045b524c04fd280bd5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Jan 2024 02:58:10 +0100 Subject: [PATCH 247/257] Add wxBitmap::CreateWithLogicalSize() This function should be used instead of CreateWithDIPSize() in portable code, the latter is currently often used to do what this function is doing, but this only works correctly in wxOSX and wxGTK3 but not wxMSW. --- include/wx/bitmap.h | 14 +++++++++++++ include/wx/msw/bitmap.h | 8 ++++++++ interface/wx/bitmap.h | 41 +++++++++++++++++++++++++++++++++++++++ src/msw/bitmap.cpp | 11 +++++++++++ tests/graphics/bitmap.cpp | 14 +++++++++++++ 5 files changed, 88 insertions(+) diff --git a/include/wx/bitmap.h b/include/wx/bitmap.h index 3a9f63aa1f..758b537a94 100644 --- a/include/wx/bitmap.h +++ b/include/wx/bitmap.h @@ -178,6 +178,11 @@ public: virtual bool Create(int width, int height, int depth = wxBITMAP_SCREEN_DEPTH) = 0; virtual bool Create(const wxSize& sz, int depth = wxBITMAP_SCREEN_DEPTH) = 0; + // DIP size and logical size are the same thing for ports using scaling, + // i.e. where physical and logical sizes are different (e.g. wxGTK and + // wxOSX), but we want to have both sets of functions to use them in the + // ports where physical and logical sizes are the same (wxMSW). + bool CreateWithDIPSize(const wxSize& sz, double scale, int depth = wxBITMAP_SCREEN_DEPTH) @@ -187,6 +192,15 @@ public: int depth = wxBITMAP_SCREEN_DEPTH) { return DoCreate(wxSize(width, height), scale, depth); } + bool CreateWithLogicalSize(const wxSize& sz, + double scale, + int depth = wxBITMAP_SCREEN_DEPTH) + { return DoCreate(sz, scale, depth); } + bool CreateWithLogicalSize(int width, int height, + double scale, + int depth = wxBITMAP_SCREEN_DEPTH) + { return DoCreate(wxSize(width, height), scale, depth); } + virtual int GetHeight() const = 0; virtual int GetWidth() const = 0; virtual int GetDepth() const = 0; diff --git a/include/wx/msw/bitmap.h b/include/wx/msw/bitmap.h index 403e6e91c1..6b5cd6efe6 100644 --- a/include/wx/msw/bitmap.h +++ b/include/wx/msw/bitmap.h @@ -157,6 +157,14 @@ public: int depth = wxBITMAP_SCREEN_DEPTH) { return CreateWithDIPSize(wxSize(width, height), scale, depth); } + bool CreateWithLogicalSize(const wxSize& sz, + double scale, + int depth = wxBITMAP_SCREEN_DEPTH); + bool CreateWithLogicalSize(int width, int height, + double scale, + int depth = wxBITMAP_SCREEN_DEPTH) + { return CreateWithLogicalSize(wxSize(width, height), scale, depth); } + virtual bool LoadFile(const wxString& name, wxBitmapType type = wxBITMAP_DEFAULT_TYPE); virtual bool SaveFile(const wxString& name, wxBitmapType type, const wxPalette *cmap = nullptr) const; diff --git a/interface/wx/bitmap.h b/interface/wx/bitmap.h index 8ab0897534..2d3eff7d05 100644 --- a/interface/wx/bitmap.h +++ b/interface/wx/bitmap.h @@ -494,6 +494,10 @@ public: Create a bitmap specifying its size in DPI-independent pixels and the scale factor to use. + This should be used when the bitmap size is fixed (e.g. at + compile-time) and not if it comes from wxWindow::GetSize() or other + similar functions -- use CreateWithLogicalSize() in the latter case. + The physical size of the bitmap is obtained by multiplying the given @a size by @a scale and rounding it to the closest integer. @@ -524,6 +528,43 @@ public: double scale, int depth = wxBITMAP_SCREEN_DEPTH); + /** + Create a bitmap specifying its size in logical pixels and the scale + factor to use. + + This should be typically used when creating bitmaps associated to a + window area, e.g. to create a bitmap covering the entire window the + @a size parameter should be wxWindow::GetClientSize() and @a scale + should be the wxWindow::GetDPIScaleFactor(). + + The physical size of the bitmap created by this function depends on the + platform and will be the same as @a size on the platforms for which + `wxHAS_DPI_INDEPENDENT_PIXELS` is not defined (e.g. wxMSW) or @a size + multiplied by @a scale for those where it is (e.g. wxGTK3 and wxOSX). + In other words, this function is the same as CreateWithDIPSize() if + `wxHAS_DPI_INDEPENDENT_PIXELS` is defined, but not otherwise. + + @param size + The size of the bitmap in logical pixels. Both width and + height must be strictly positive. + @param scale + Scale factor used by the bitmap, see SetScaleFactor(). + @param depth + The number of bits used to represent each bitmap pixel. + + @return @true if the creation was successful. + + @since 3.3.0 + */ + bool CreateWithLogicalSize(const wxSize& size, + double scale, + int depth = wxBITMAP_SCREEN_DEPTH); + + /// @overload + bool CreateWithLogicalSize(int width, int height, + double scale, + int depth = wxBITMAP_SCREEN_DEPTH); + /** Create a bitmap with a scale factor. diff --git a/src/msw/bitmap.cpp b/src/msw/bitmap.cpp index 334917c28e..6f06027f14 100644 --- a/src/msw/bitmap.cpp +++ b/src/msw/bitmap.cpp @@ -775,6 +775,17 @@ bool wxBitmap::CreateWithDIPSize(const wxSize& size, double scale, int depth) return true; } +bool +wxBitmap::CreateWithLogicalSize(const wxSize& size, double scale, int depth) +{ + if ( !Create(size, depth) ) + return false; + + GetBitmapData()->m_scaleFactor = scale; + + return true; +} + bool wxBitmap::DoCreate(int w, int h, int d, WXHDC hdc) { UnRef(); diff --git a/tests/graphics/bitmap.cpp b/tests/graphics/bitmap.cpp index eeb4bf7b54..7f9e901d5d 100644 --- a/tests/graphics/bitmap.cpp +++ b/tests/graphics/bitmap.cpp @@ -1848,6 +1848,20 @@ TEST_CASE("Bitmap::ScaleFactor", "[bitmap][dc][scale]") wxBitmap bmp3(img, dc); CHECK( bmp3.GetScaleFactor() == 2 ); CHECK( bmp3.GetSize() == wxSize(16, 16) ); + + // And another way to create a bitmap with specified scale factor. + const wxSize sizeLog(10, 10); + + wxBitmap bmp4; + bmp4.CreateWithLogicalSize(sizeLog, 2); + CHECK( bmp4.GetScaleFactor() == 2 ); + CHECK( bmp4.GetLogicalSize() == sizeLog ); + +#ifdef wxHAS_DPI_INDEPENDENT_PIXELS + CHECK( bmp4.GetSize() == 2*sizeLog ); +#else + CHECK( bmp4.GetSize() == sizeLog ); +#endif } TEST_CASE("wxBitmap::GetSubBitmap", "[bitmap]") From 2cef35b32148fe921e04b826ec04fb222c26c2f6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Jan 2024 03:04:55 +0100 Subject: [PATCH 248/257] Use wxBitmap::CreateWithLogicalSize() in wxMSW wxStaticBox code This is slightly simpler and hopefully more clear than creating bitmap using the physical size and then setting the scale factor. No real changes. --- src/msw/statbox.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/msw/statbox.cpp b/src/msw/statbox.cpp index 6ef086b73d..05e7114fd9 100644 --- a/src/msw/statbox.cpp +++ b/src/msw/statbox.cpp @@ -718,8 +718,9 @@ void wxStaticBox::OnPaint(wxPaintEvent& WXUNUSED(event)) wxMemoryDC memdc(&dc); const double scale = dc.GetContentScaleFactor(); - wxBitmap bitmap(rc.right, rc.bottom); - bitmap.SetScaleFactor(scale); + wxBitmap bitmap; + // Physical and logical sizes are the same in wxMSW. + bitmap.CreateWithLogicalSize(rc.right, rc.bottom, scale); memdc.SelectObject(bitmap); PaintBackground(memdc, rc); From d254a7d752734db9e8d13fddb695f498e716f392 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Jan 2024 03:05:37 +0100 Subject: [PATCH 249/257] Use wxBitmap::CreateWithLogicalSize() in wxSTC code This is simpler than using ToPhys() to explicitly compute the needed bitmap size and more clear. No real changes. --- src/stc/PlatWX.cpp | 4 ++-- src/stc/ScintillaWX.cpp | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/stc/PlatWX.cpp b/src/stc/PlatWX.cpp index 423fd55578..0dc2bdb749 100644 --- a/src/stc/PlatWX.cpp +++ b/src/stc/PlatWX.cpp @@ -292,8 +292,8 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface, WindowID w hdcOwned = true; if (width < 1) width = 1; if (height < 1) height = 1; - bitmap = new wxBitmap(GETWIN(winid)->ToPhys(wxSize(width, height))); - bitmap->SetScaleFactor(GETWIN(winid)->GetDPIScaleFactor()); + bitmap = new wxBitmap(); + bitmap->CreateWithLogicalSize(width, height, GETWIN(winid)->GetDPIScaleFactor()); mdc->SelectObject(*bitmap); } diff --git a/src/stc/ScintillaWX.cpp b/src/stc/ScintillaWX.cpp index 48f17ee383..32d90f334b 100644 --- a/src/stc/ScintillaWX.cpp +++ b/src/stc/ScintillaWX.cpp @@ -109,8 +109,7 @@ public: void DrawBack(const wxSize& size) { - m_back = wxBitmap(ToPhys(size)); - m_back.SetScaleFactor(GetDPIScaleFactor()); + m_back.CreateWithLogicalSize(size, GetDPIScaleFactor()); wxMemoryDC mem(m_back); Surface* surfaceWindow = Surface::Allocate(m_swx->technology); surfaceWindow->Init(&mem, m_ct->wDraw.GetID()); From 006a84db149907d34e8d3e6bbb3a9f360d4282e0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Jan 2024 03:10:37 +0100 Subject: [PATCH 250/257] Use CreateWithLogicalSize() instead of ...DIPSize() in wxOSX These functions behave in exactly the same way in this port, but using CreateWithLogicalSize() seems to be more clear, as we're passing it the coordinates in logical pixels (e.g. window sizes etc) and not DIPs. No real changes. --- src/osx/cocoa/utils.mm | 4 ++-- src/osx/core/bitmap.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/osx/cocoa/utils.mm b/src/osx/cocoa/utils.mm index 96cf8cbfc0..b13d85b1b7 100644 --- a/src/osx/cocoa/utils.mm +++ b/src/osx/cocoa/utils.mm @@ -585,7 +585,7 @@ wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const const wxSize bitmapSize(subrect ? subrect->GetSize() : m_window->GetSize()); wxBitmap bitmap; - bitmap.CreateWithDIPSize(bitmapSize, m_contentScaleFactor); + bitmap.CreateWithLogicalSize(bitmapSize, m_contentScaleFactor); NSView* view = (NSView*) m_window->GetHandle(); if ( [view isHiddenOrHasHiddenAncestor] == NO ) @@ -617,7 +617,7 @@ wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) ); - // The bitmap created by wxBitmap::CreateWithDIPSize() above is scaled, + // The bitmap created by wxBitmap::CreateWithLogicalSize() above is scaled, // so we need to adjust the coordinates for it. r.size.width /= m_contentScaleFactor; r.size.height /= m_contentScaleFactor; diff --git a/src/osx/core/bitmap.cpp b/src/osx/core/bitmap.cpp index 20718d0e13..e2f31c8c76 100644 --- a/src/osx/core/bitmap.cpp +++ b/src/osx/core/bitmap.cpp @@ -973,7 +973,7 @@ wxBitmap wxBitmap::GetSubBitmap(const wxRect &rect) const wxBitmap ret; double scale = GetScaleFactor(); - ret.CreateWithDIPSize( rect.GetSize(), scale, GetDepth() ); + ret.CreateWithLogicalSize( rect.GetSize(), scale, GetDepth() ); wxASSERT_MSG( ret.IsOk(), wxT("GetSubBitmap error") ); if ( HasAlpha() ) ret.UseAlpha() ; From 6655f6e41cfee7d5cd457eac0ff1a275443b99b5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 9 Jan 2024 03:12:56 +0100 Subject: [PATCH 251/257] Fix wrong uses of wxBitmap::CreateWithDIPSize() In portable code CreateWithLogicalSize() must be used when its arguments are logical coordinates, e.g. window sizes, so using CreateWithDIPSize() was wrong and resulted in missized bitmaps in high DPI under MSW. --- src/common/animatecmn.cpp | 2 +- src/common/dcbufcmn.cpp | 2 +- src/generic/wizard.cpp | 2 +- src/msw/overlay.cpp | 2 +- src/propgrid/propgrid.cpp | 8 ++++---- src/richtext/richtextctrl.cpp | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/common/animatecmn.cpp b/src/common/animatecmn.cpp index 9a80ce3add..282fc2e9da 100644 --- a/src/common/animatecmn.cpp +++ b/src/common/animatecmn.cpp @@ -173,7 +173,7 @@ void wxAnimationCtrlBase::UpdateStaticImage() m_bmpStaticReal.GetLogicalHeight() != sz.GetHeight()) { // need to (re)create m_bmpStaticReal - if (!m_bmpStaticReal.CreateWithDIPSize(sz, + if (!m_bmpStaticReal.CreateWithLogicalSize(sz, bmpCurrent.GetScaleFactor(), bmpCurrent.GetDepth())) { diff --git a/src/common/dcbufcmn.cpp b/src/common/dcbufcmn.cpp index db0e001fba..ba31002c1d 100644 --- a/src/common/dcbufcmn.cpp +++ b/src/common/dcbufcmn.cpp @@ -84,7 +84,7 @@ private: // we must always return a valid bitmap but creating a bitmap of // size 0 would fail, so create a 1*1 bitmap in this case - buffer->CreateWithDIPSize(wxMax(w, 1), wxMax(h, 1), scale); + buffer->CreateWithLogicalSize(wxMax(w, 1), wxMax(h, 1), scale); return buffer; } diff --git a/src/generic/wizard.cpp b/src/generic/wizard.cpp index bb0978936b..a346e0be14 100644 --- a/src/generic/wizard.cpp +++ b/src/generic/wizard.cpp @@ -999,7 +999,7 @@ bool wxWizard::ResizeBitmap(wxBitmap& bmp) if (!m_statbmp->GetBitmap().IsOk() || m_statbmp->GetBitmap().GetLogicalHeight() != bitmapHeight) { wxBitmap bitmap; - bitmap.CreateWithDIPSize(bitmapWidth, bitmapHeight, bmp.GetScaleFactor(), bmp.GetDepth()); + bitmap.CreateWithLogicalSize(bitmapWidth, bitmapHeight, bmp.GetScaleFactor(), bmp.GetDepth()); { wxMemoryDC dc; dc.SelectObject(bitmap); diff --git a/src/msw/overlay.cpp b/src/msw/overlay.cpp index 030df35636..7df05aca45 100644 --- a/src/msw/overlay.cpp +++ b/src/msw/overlay.cpp @@ -103,7 +103,7 @@ void wxOverlayImpl::Init(wxDC* dc, int , int , int , int ) m_rect.SetSize(m_window->GetClientSize()); m_rect.SetPosition(m_window->GetScreenPosition()); - m_bitmap.CreateWithDIPSize(m_rect.GetSize(), m_window->GetDPIScaleFactor()); + m_bitmap.CreateWithLogicalSize(m_rect.GetSize(), m_window->GetDPIScaleFactor()); m_overlayWindow = wxCreateOverlayWindow(m_rect); } diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 5f902410b7..7112061fca 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -4607,10 +4607,10 @@ void wxPropertyGrid::OnResize( wxSizeEvent& event ) if ( !m_doubleBuffer ) { // Create double buffer bitmap to draw on, if none - int w = wxMax(width, 250); - int h = wxMax(height + dblh, 400); + int w = wxMax(width, FromDIP(250)); + int h = wxMax(height + dblh, FromDIP(400)); m_doubleBuffer = new wxBitmap; - m_doubleBuffer->CreateWithDIPSize( w, h, scaleFactor ); + m_doubleBuffer->CreateWithLogicalSize( w, h, scaleFactor ); } else { @@ -4624,7 +4624,7 @@ void wxPropertyGrid::OnResize( wxSizeEvent& event ) if ( h < (height+dblh) ) h = height + dblh; delete m_doubleBuffer; m_doubleBuffer = new wxBitmap; - m_doubleBuffer->CreateWithDIPSize( w, h, scaleFactor ); + m_doubleBuffer->CreateWithLogicalSize( w, h, scaleFactor ); } } } diff --git a/src/richtext/richtextctrl.cpp b/src/richtext/richtextctrl.cpp index 953a6f2e85..3f87011627 100644 --- a/src/richtext/richtextctrl.cpp +++ b/src/richtext/richtextctrl.cpp @@ -3029,7 +3029,7 @@ bool wxRichTextCtrl::RecreateBuffer(const wxSize& size) #if defined(__WXMSW__) depth = 24; #endif - m_bufferBitmap.CreateWithDIPSize(sz, GetDPIScaleFactor(), depth); + m_bufferBitmap.CreateWithLogicalSize(sz, GetDPIScaleFactor(), depth); } return m_bufferBitmap.IsOk(); } From c1b7ce593279b4281879cd4e0cf4a6b8d53a9a5c Mon Sep 17 00:00:00 2001 From: mcorino Date: Wed, 10 Jan 2024 14:46:51 +0100 Subject: [PATCH 252/257] Fix typing error in interface def. missing whitespace between arg type and name --- interface/wx/propgrid/props.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/wx/propgrid/props.h b/interface/wx/propgrid/props.h index 16d9636b37..21fabaebb5 100644 --- a/interface/wx/propgrid/props.h +++ b/interface/wx/propgrid/props.h @@ -218,7 +218,7 @@ public: virtual wxString ValueToString(wxVariant& value, wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool StringToValue(wxVariant& variant, const wxString& text, - wxPGPropValFormatFlagsflags = wxPGPropValFormatFlags::Null) const; + wxPGPropValFormatFlags flags = wxPGPropValFormatFlags::Null) const; virtual bool ValidateValue( wxVariant& value, wxPGValidationInfo& validationInfo ) const; virtual bool IntToValue(wxVariant& variant, int number, From 340bbea71dae6170677943cfaac211288c4a54bb Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 10 Jan 2024 18:07:36 +0100 Subject: [PATCH 253/257] Remove irrelevant mentions of encoding from wxXmlDocument docs The corresponding parameter was removed in cc8fbeed56 (Merge branch 'xml-conv-simplify', 2024-01-07) but it was still mentioned in the description. --- interface/wx/xml/xml.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/wx/xml/xml.h b/interface/wx/xml/xml.h index 0d6b5a960a..88c66712a4 100644 --- a/interface/wx/xml/xml.h +++ b/interface/wx/xml/xml.h @@ -709,12 +709,12 @@ public: wxXmlDocument(const wxXmlDocument& doc); /** - Loads the given filename using the given encoding. See Load(). + Loads the given filename. See Load(). */ wxXmlDocument(const wxString& filename); /** - Loads the XML document from given stream using the given encoding. See Load(). + Loads the XML document from given stream. See Load(). */ wxXmlDocument(wxInputStream& stream); From 78a8da714269db3a81eaac9a0f0b5e56fd270998 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 10 Jan 2024 18:15:47 +0100 Subject: [PATCH 254/257] Fix a typo in comment in wxGCDC::DoStretchBlit() No real changes. --- src/common/dcgraph.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/dcgraph.cpp b/src/common/dcgraph.cpp index e0a5b0f6eb..caed52e0bd 100644 --- a/src/common/dcgraph.cpp +++ b/src/common/dcgraph.cpp @@ -1048,7 +1048,7 @@ bool wxGCDCImpl::DoStretchBlit( wxCompositionMode mode = TranslateRasterOp(logical_func); if ( mode == wxCOMPOSITION_INVALID ) { - // Do *not* assert here, this function is often call from wxEVT_PAINT + // Do *not* assert here, this function is often called from wxEVT_PAINT // handler and asserting will just result in a reentrant call to the // same handler and a crash. return false; From 56d857152d0d87fcbbbfe08904bd15d3e288bdf8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 11 Jan 2024 00:49:32 +0100 Subject: [PATCH 255/257] Don't use comma operator in wxPoint operators This was probably done unintentionally in 8ccbd7e95d (Implement operator/=(int) and operator*=(int) for wxPoint and wxRealPoint., 2024-01-04) and results in warnings from clang. --- include/wx/gdicmn.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 555ee6985a..56ab3adf38 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -620,8 +620,8 @@ public: wxPoint& operator+=(const wxSize& s) { x += s.GetWidth(); y += s.GetHeight(); return *this; } wxPoint& operator-=(const wxSize& s) { x -= s.GetWidth(); y -= s.GetHeight(); return *this; } - wxPoint& operator/=(int i) { x /= i, y /= i; return *this; } - wxPoint& operator*=(int i) { x *= i, y *= i; return *this; } + wxPoint& operator/=(int i) { x /= i; y /= i; return *this; } + wxPoint& operator*=(int i) { x *= i; y *= i; return *this; } wxPoint& operator/=(double f) { x = wxRound(x/f); y = wxRound(y/f); return *this; } wxPoint& operator*=(double f) { x = wxRound(x*f); y = wxRound(y*f); return *this; } From 81e9373efa99aede6a9cd6d280b5671fe8e44be3 Mon Sep 17 00:00:00 2001 From: DietmarSchwertberger Date: Thu, 11 Jan 2024 19:50:00 +0100 Subject: [PATCH 256/257] Add missing documentation of wxWindow accessibility functions Ensure they're present in the interface header as this is also required for wrapping them in other languages, such as Python. Closes #24209. --- interface/wx/window.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/interface/wx/window.h b/interface/wx/window.h index 392f1aa3a6..1a098089e1 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -3462,6 +3462,17 @@ public: */ void SetAccessible(wxAccessible* accessible); + /** + Override to create a specific accessible object. + */ + virtual wxAccessible* CreateAccessible(); + + /** + Returns the accessible object, calling CreateAccessible if necessary. + May return NULL, in which case system-provide accessible is used. + */ + wxAccessible* GetOrCreateAccessible(); + ///@} From b822d7d9e15e3286c244e6eaac4c4142ca2b0364 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 12 Jan 2024 18:36:24 +0100 Subject: [PATCH 257/257] Fix use of "NULL" in GetOrCreateAccessible() documentation This should have been part of 81e9373efa (Add missing documentation of wxWindow accessibility functions, 2024-01-11). --- interface/wx/window.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/wx/window.h b/interface/wx/window.h index 1a098089e1..e83cb6ffeb 100644 --- a/interface/wx/window.h +++ b/interface/wx/window.h @@ -3469,7 +3469,7 @@ public: /** Returns the accessible object, calling CreateAccessible if necessary. - May return NULL, in which case system-provide accessible is used. + May return @NULL, in which case system-provide accessible is used. */ wxAccessible* GetOrCreateAccessible();