1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/qt/menuitem.cpp
3 // Author:      Peter Most, Mariano Reingart
4 // Copyright:   (c) 2010 wxWidgets dev team
5 // Licence:     wxWindows licence
6 /////////////////////////////////////////////////////////////////////////////
7 
8 // For compilers that support precompilation, includes "wx.h".
9 #include "wx/wxprec.h"
10 
11 #include "wx/menuitem.h"
12 #include "wx/menu.h"
13 #include "wx/bitmap.h"
14 #include "wx/qt/private/utils.h"
15 #include "wx/qt/private/converter.h"
16 #include "wx/qt/private/winevent.h"
17 
18 #include <QtWidgets/QAction>
19 #include <QtWidgets/QMenuBar>
20 
21 class wxQtAction : public QAction, public wxQtSignalHandler< wxMenuItem >
22 {
23 
24 public:
25     wxQtAction( wxMenu *parent, int id, const wxString &text, const wxString &help,
26         wxItemKind kind, wxMenu *subMenu, wxMenuItem *handler );
27 
28     // Set the action shortcut to correspond to the accelerator specified by
29     // the given label.
30     void UpdateShortcutsFromLabel(const wxString& text);
31 
32 private:
33     void onActionTriggered( bool checked );
34 };
35 
36 
New(wxMenu * parentMenu,int id,const wxString & name,const wxString & help,wxItemKind kind,wxMenu * subMenu)37 wxMenuItem *wxMenuItemBase::New(wxMenu *parentMenu, int id, const wxString& name,
38     const wxString& help, wxItemKind kind, wxMenu *subMenu)
39 {
40     return new wxMenuItem(parentMenu, id, name, help, kind, subMenu);
41 }
42 
43 
44 
wxMenuItem(wxMenu * parentMenu,int id,const wxString & text,const wxString & help,wxItemKind kind,wxMenu * subMenu)45 wxMenuItem::wxMenuItem(wxMenu *parentMenu, int id, const wxString& text,
46         const wxString& help, wxItemKind kind, wxMenu *subMenu)
47     : wxMenuItemBase( parentMenu, id, text, help, kind, subMenu )
48 {
49     m_qtAction = new wxQtAction( parentMenu, id, text, help, kind, subMenu, this );
50 }
51 
52 
53 
SetItemLabel(const wxString & label)54 void wxMenuItem::SetItemLabel( const wxString &label )
55 {
56     wxMenuItemBase::SetItemLabel( label );
57 
58     m_qtAction->UpdateShortcutsFromLabel( label );
59 
60     m_qtAction->setText( wxQtConvertString( label ));
61 }
62 
63 
64 
SetCheckable(bool checkable)65 void wxMenuItem::SetCheckable( bool checkable )
66 {
67     wxMenuItemBase::SetCheckable( checkable );
68 
69     m_qtAction->setCheckable( checkable );
70 }
71 
72 
73 
Enable(bool enable)74 void wxMenuItem::Enable( bool enable )
75 {
76     wxMenuItemBase::Enable( enable );
77 
78     m_qtAction->setEnabled( enable );
79 }
80 
81 
82 
IsEnabled() const83 bool wxMenuItem::IsEnabled() const
84 {
85     bool isEnabled = m_qtAction->isEnabled();
86 
87     // Make sure the enabled stati are in synch:
88     wxASSERT( isEnabled == wxMenuItemBase::IsEnabled() );
89 
90     return isEnabled;
91 }
92 
93 
94 
Check(bool checked)95 void wxMenuItem::Check( bool checked )
96 {
97     wxMenuItemBase::Check( checked );
98 
99     m_qtAction->setChecked( checked );
100 }
101 
102 
103 
IsChecked() const104 bool wxMenuItem::IsChecked() const
105 {
106     bool isChecked = m_qtAction->isChecked();
107 
108     // Make sure the checked stati are in synch:
109     wxASSERT( isChecked == wxMenuItemBase::IsChecked() );
110 
111     return isChecked;
112 }
113 
114 
SetBitmap(const wxBitmap & bitmap)115 void wxMenuItem::SetBitmap(const wxBitmap& bitmap)
116 {
117     if ( m_kind == wxITEM_NORMAL )
118     {
119         m_bitmap = bitmap;
120         if ( !m_bitmap.IsNull() )
121         {
122             m_qtAction->setIcon( QIcon(*m_bitmap.GetHandle()) );
123         }
124     }
125     else
126     {
127         wxFAIL_MSG("only normal menu items can have bitmaps");
128     }
129 }
130 
SetFont(const wxFont & font)131 void wxMenuItem::SetFont(const wxFont& font)
132 {
133     m_qtAction->setFont(font.GetHandle());
134 }
135 
GetHandle() const136 QAction *wxMenuItem::GetHandle() const
137 {
138     return m_qtAction;
139 }
140 
141 //=============================================================================
142 
wxQtAction(wxMenu * parent,int id,const wxString & text,const wxString & help,wxItemKind kind,wxMenu * subMenu,wxMenuItem * handler)143 wxQtAction::wxQtAction( wxMenu *parent, int id, const wxString &text, const wxString &help,
144         wxItemKind kind, wxMenu *subMenu, wxMenuItem *handler )
145     : QAction( wxQtConvertString( text ), parent->GetHandle() ),
146       wxQtSignalHandler< wxMenuItem >( handler )
147 {
148     setStatusTip( wxQtConvertString( help ));
149 
150     if ( subMenu != NULL )
151         setMenu( subMenu->GetHandle() );
152 
153     if ( id == wxID_SEPARATOR )
154         setSeparator( true );
155 
156     switch ( kind )
157     {
158         case wxITEM_SEPARATOR:
159             setSeparator( true );
160             break;
161         case wxITEM_CHECK:
162         case wxITEM_RADIO:
163             setCheckable( true );
164             break;
165         case wxITEM_NORMAL:
166             // Normal for a menu item.
167             break;
168         case wxITEM_DROPDOWN:
169         case wxITEM_MAX:
170             // Not applicable for menu items.
171             break;
172     }
173 
174     connect( this, &QAction::triggered, this, &wxQtAction::onActionTriggered );
175 
176     UpdateShortcutsFromLabel( text );
177 }
178 
UpdateShortcutsFromLabel(const wxString & text)179 void wxQtAction::UpdateShortcutsFromLabel(const wxString& text)
180 {
181 #if wxUSE_ACCEL
182     const wxString accelStr = text.AfterFirst('\t');
183     if ( !accelStr.empty() )
184     {
185         setShortcut(  QKeySequence( wxQtConvertString(accelStr) ) );
186     }
187 #endif // wxUSE_ACCEL
188 }
189 
onActionTriggered(bool checked)190 void wxQtAction::onActionTriggered( bool checked )
191 {
192     wxMenuItem *handler = GetHandler();
193     wxMenu *menu = handler->GetMenu();
194     if ( handler->IsCheckable() )
195         handler->Check(checked);
196     menu->SendEvent( handler->GetId(), handler->IsCheckable() ? checked : -1 );
197 }
198