Merge branch 'qt-some-cleanups' of https://github.com/AliKet/wxWidgets

Some more wxQt fixes and cleanups.

See #24210.
This commit is contained in:
Vadim Zeitlin 2024-01-19 02:47:52 +01:00
commit ee691af12d
5 changed files with 101 additions and 97 deletions

View file

@ -12,7 +12,6 @@
#include "wx/bitmap.h"
class QAction;
class wxQtAction;
class WXDLLIMPEXP_FWD_CORE wxMenu;
@ -35,8 +34,6 @@ public:
virtual void Check(bool check = true) override;
virtual bool IsChecked() const override;
virtual void SetBitmap(const wxBitmapBundle& bitmap) override;
virtual QAction *GetHandle() const;
virtual void SetFont(const wxFont& font);
@ -46,9 +43,12 @@ public:
virtual void ClearExtraAccels() override;
#endif // wxUSE_ACCEL
// implementation
void QtCreateAction(wxMenu* parentMenu);
private:
// Qt is using an action instead of a menu item.
wxQtAction *m_qtAction;
QAction *m_qtAction = nullptr;
wxDECLARE_DYNAMIC_CLASS( wxMenuItem );
};

View file

@ -30,21 +30,17 @@ class QPaintEvent;
class wxQtSignalHandler
{
protected:
wxQtSignalHandler( wxEvtHandler *handler )
explicit wxQtSignalHandler( wxWindow *handler ) : m_handler(handler)
{
m_handler = handler;
}
bool EmitEvent( wxEvent &event ) const
{
// We're only called with the objects of class (or derived from)
// wxWindow, so the cast is safe.
wxWindow* const handler = static_cast<wxWindow *>(GetHandler());
event.SetEventObject( handler );
return handler->HandleWindowEvent( event );
event.SetEventObject( m_handler );
return m_handler->HandleWindowEvent( event );
}
virtual wxEvtHandler *GetHandler() const
virtual wxWindow *GetHandler() const
{
return m_handler;
}
@ -54,22 +50,18 @@ protected:
// event if the control has wxTE_PROCESS_ENTER flag.
bool HandleKeyPressEvent(QWidget* widget, QKeyEvent* e)
{
// We're only called with the objects of class (or derived from)
// wxWindow, so the cast is safe.
wxWindow* const handler = static_cast<wxWindow *>(GetHandler());
if ( handler->HasFlag(wxTE_PROCESS_ENTER) )
if ( m_handler->HasFlag(wxTE_PROCESS_ENTER) )
{
if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter )
{
wxCommandEvent event( wxEVT_TEXT_ENTER, handler->GetId() );
wxCommandEvent event( wxEVT_TEXT_ENTER, m_handler->GetId() );
event.SetString( GetValueForProcessEnter() );
event.SetEventObject( handler );
return handler->HandleWindowEvent( event );
event.SetEventObject( m_handler );
return m_handler->HandleWindowEvent( event );
}
}
return handler->QtHandleKeyEvent(widget, e);
return m_handler->QtHandleKeyEvent(widget, e);
}
// Controls supporting wxTE_PROCESS_ENTER flag (e.g. wxTextCtrl, wxComboBox and wxSpinCtrl)
@ -77,7 +69,7 @@ protected:
virtual wxString GetValueForProcessEnter() { return wxString(); }
private:
wxEvtHandler *m_handler;
wxWindow* const m_handler;
};
template < typename Widget, typename Handler >

View file

@ -25,13 +25,12 @@ static void ApplyStyle( QMenu *qtMenu, long style )
// wxQtActionGroup: an exclusive group which synchronizes QActions in
// QActionGroup with their wx wrappers.
class wxQtActionGroup : public QActionGroup, public wxQtSignalHandler
class wxQtActionGroup : public QActionGroup
{
public:
explicit wxQtActionGroup( wxMenu* handler )
: QActionGroup( handler->GetHandle() ),
wxQtSignalHandler( handler )
: QActionGroup( handler->GetHandle() )
{
setExclusive(true);
@ -44,7 +43,16 @@ public:
}
private:
void triggered ( QAction* action );
void triggered ( QAction* action )
{
if ( action != m_activeAction )
{
if ( m_activeAction->isCheckable() )
m_activeAction->setChecked(false);
m_activeAction = action;
}
}
QAction* m_activeAction;
};
@ -168,6 +176,8 @@ wxMenuItem *wxMenu::DoAppend(wxMenuItem *item)
if ( wxMenuBase::DoAppend( item ) == nullptr )
return nullptr;
item->QtCreateAction( this );
InsertMenuItemAction( this, previousItem, item, successiveItem );
return item;
@ -185,6 +195,8 @@ wxMenuItem *wxMenu::DoInsert(size_t insertPosition, wxMenuItem *item)
if ( wxMenuBase::DoInsert( insertPosition, item ) == nullptr )
return nullptr;
item->QtCreateAction( this );
InsertMenuItemAction( this, previousItem, item, successiveItem );
return item;
@ -342,14 +354,3 @@ QWidget *wxMenuBar::GetHandle() const
{
return m_qtMenuBar;
}
void wxQtActionGroup::triggered( QAction* action )
{
if ( action != m_activeAction )
{
if ( m_activeAction->isCheckable() )
m_activeAction->setChecked(false);
m_activeAction = action;
}
}

View file

@ -18,12 +18,12 @@
#include <QtWidgets/QAction>
#include <QtWidgets/QMenuBar>
class wxQtAction : public QAction, public wxQtSignalHandler
class wxQtAction : public QAction
{
public:
wxQtAction( wxMenu *handler, int id, const wxString &text, const wxString &help,
wxItemKind kind, wxMenu *subMenu, wxMenuItem *menuItem );
wxItemKind kind, wxMenu *subMenu, wxMenuItem *menuItem );
// Set the action shortcut to correspond to the accelerator specified by
// the given label. They set the primary shortcut the first time they are
@ -32,11 +32,6 @@ public:
void UpdateShortcuts(const wxString& text);
void UpdateShortcutsFromLabel(const wxString& text);
wxMenu* GetMenu() const
{
return static_cast<wxMenu*>(wxQtSignalHandler::GetHandler());
}
// Convert hyphenated shortcuts to use the plus sign (+) which Qt understands.
// Example: [ Ctrl-Shift-- ] should be converted to [ Ctrl+Shift+- ]
static wxString Normalize(const wxString& text)
@ -47,9 +42,17 @@ public:
}
private:
void onActionToggled( bool checked );
void onActionTriggered( bool checked );
void onActionToggled( bool checked )
{
m_handler->Check(m_mitemId, checked);
}
void onActionTriggered( bool checked )
{
m_handler->SendEvent(m_mitemId, m_isCheckable ? checked : -1);
}
wxMenu* m_handler;
const wxWindowID m_mitemId;
const bool m_isCheckable;
};
@ -67,11 +70,27 @@ wxMenuItem::wxMenuItem(wxMenu *parentMenu, int id, const wxString& text,
const wxString& help, wxItemKind kind, wxMenu *subMenu)
: wxMenuItemBase( parentMenu, id, text, help, kind, subMenu )
{
m_qtAction = new wxQtAction( parentMenu, id,
wxQtAction::Normalize( text ),
help, kind, subMenu, this );
}
void wxMenuItem::QtCreateAction(wxMenu* parentMenu)
{
wxASSERT_MSG( parentMenu, "invalid parent" );
m_qtAction = new wxQtAction( parentMenu, GetId(),
wxQtAction::Normalize( GetItemLabel() ),
GetHelp(), GetKind(), GetSubMenu(), this );
if ( m_bitmap.IsOk() && m_kind == wxITEM_NORMAL )
{
m_qtAction->setIcon( QIcon(*GetBitmapFromBundle(m_bitmap).GetHandle()) );
}
#if wxUSE_ACCEL
auto qtAction = static_cast<wxQtAction *>(m_qtAction);
for ( const auto accel : m_extraAccels )
qtAction->UpdateShortcuts( accel.ToRawString() );
#endif
}
void wxMenuItem::SetItemLabel( const wxString &label )
@ -80,15 +99,21 @@ void wxMenuItem::SetItemLabel( const wxString &label )
wxMenuItemBase::SetItemLabel( qtlabel );
m_qtAction->UpdateShortcutsFromLabel( qtlabel );
if ( m_qtAction )
{
auto qtAction = static_cast<wxQtAction *>(m_qtAction);
m_qtAction->setText( wxQtConvertString( qtlabel ));
qtAction->UpdateShortcutsFromLabel( qtlabel );
qtAction->setText( wxQtConvertString( qtlabel ));
}
}
void wxMenuItem::SetCheckable( bool checkable )
{
wxCHECK_RET( m_qtAction, "invalid menu item" );
wxMenuItemBase::SetCheckable( checkable );
m_qtAction->setCheckable( checkable );
@ -98,6 +123,8 @@ void wxMenuItem::SetCheckable( bool checkable )
void wxMenuItem::Enable( bool enable )
{
wxCHECK_RET( m_qtAction, "invalid menu item" );
wxMenuItemBase::Enable( enable );
m_qtAction->setEnabled( enable );
@ -107,6 +134,8 @@ void wxMenuItem::Enable( bool enable )
bool wxMenuItem::IsEnabled() const
{
wxCHECK_MSG( m_qtAction, false, "invalid menu item" );
bool isEnabled = m_qtAction->isEnabled();
// Make sure the enabled stati are in synch:
@ -119,6 +148,8 @@ bool wxMenuItem::IsEnabled() const
void wxMenuItem::Check( bool checked )
{
wxCHECK_RET( m_qtAction, "invalid menu item" );
wxMenuItemBase::Check( checked );
m_qtAction->setChecked( checked );
@ -128,6 +159,11 @@ void wxMenuItem::Check( bool checked )
bool wxMenuItem::IsChecked() const
{
wxCHECK_MSG( m_qtAction, false, "invalid menu item" );
wxCHECK_MSG( IsCheckable(), false,
"can't get state of uncheckable item!" );
bool isChecked = m_qtAction->isChecked();
// Make sure the checked stati are in synch:
@ -137,24 +173,10 @@ bool wxMenuItem::IsChecked() const
}
void wxMenuItem::SetBitmap(const wxBitmapBundle& bitmap)
{
if ( m_kind == wxITEM_NORMAL )
{
m_bitmap = bitmap;
if ( m_bitmap.IsOk() )
{
m_qtAction->setIcon( QIcon(*GetBitmapFromBundle(m_bitmap).GetHandle()) );
}
}
else
{
wxFAIL_MSG("only normal menu items can have bitmaps");
}
}
void wxMenuItem::SetFont(const wxFont& font)
{
wxCHECK_RET( m_qtAction, "invalid menu item" );
m_qtAction->setFont(font.GetHandle());
}
@ -168,23 +190,25 @@ void wxMenuItem::AddExtraAccel(const wxAcceleratorEntry& accel)
{
wxMenuItemBase::AddExtraAccel(accel);
m_qtAction->UpdateShortcuts( accel.ToRawString() );
if ( m_qtAction )
static_cast<wxQtAction *>(m_qtAction)->UpdateShortcuts( accel.ToRawString() );
}
void wxMenuItem::ClearExtraAccels()
{
wxMenuItemBase::ClearExtraAccels();
m_qtAction->UpdateShortcuts( wxString() );
if ( m_qtAction )
static_cast<wxQtAction *>(m_qtAction)->UpdateShortcuts( wxString() );
}
#endif // wxUSE_ACCEL
//=============================================================================
wxQtAction::wxQtAction( wxMenu *handler, int id, const wxString &text, const wxString &help,
wxItemKind kind, wxMenu *subMenu, wxMenuItem *menuItem )
wxItemKind kind, wxMenu *subMenu, wxMenuItem *menuItem )
: QAction( wxQtConvertString( text ), handler->GetHandle() ),
wxQtSignalHandler( handler ),
m_handler(handler),
m_mitemId(menuItem->GetId()), m_isCheckable(menuItem->IsCheckable())
{
setStatusTip( wxQtConvertString( help ));
@ -259,13 +283,3 @@ void wxQtAction::UpdateShortcuts(const wxString& text)
wxUnusedVar(text);
#endif // wxUSE_ACCEL
}
void wxQtAction::onActionToggled( bool checked )
{
GetMenu()->Check(m_mitemId, checked);
}
void wxQtAction::onActionTriggered( bool checked )
{
GetMenu()->SendEvent(m_mitemId, m_isCheckable ? checked : -1 );
}

View file

@ -218,27 +218,24 @@ void wxQtScrollArea::OnSliderReleased()
}
#if wxUSE_ACCEL || defined( Q_MOC_RUN )
class wxQtShortcutHandler : public QObject, public wxQtSignalHandler
class wxQtShortcutHandler : public QObject
{
public:
wxQtShortcutHandler( wxWindowQt *window );
explicit wxQtShortcutHandler( wxWindow *handler ) : m_handler(handler) { }
public:
void activated();
void activated()
{
const int command = sender()->property("wxQt_Command").toInt();
m_handler->QtHandleShortcut( command );
}
private:
wxWindow* const m_handler;
};
wxQtShortcutHandler::wxQtShortcutHandler( wxWindowQt *window )
: wxQtSignalHandler( window )
{
}
void wxQtShortcutHandler::activated()
{
int command = sender()->property("wxQt_Command").toInt();
static_cast<wxWindowQt*>(GetHandler())->QtHandleShortcut( command );
}
#endif // wxUSE_ACCEL
//##############################################################################