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