Qt 4.8
qcocoamenuloader_mac.mm
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qmacdefines_mac.h"
43 #ifdef QT_MAC_USE_COCOA
44 #include <qaction.h>
45 #include <qcoreapplication.h>
46 #include <private/qcocoamenuloader_mac_p.h>
47 #include <private/qapplication_p.h>
48 #include <private/qt_mac_p.h>
49 #include <private/qmenubar_p.h>
50 #include <qmenubar.h>
51 #include <private/qt_cocoa_helpers_mac_p.h>
52 
55 
56 #ifndef QT_NO_TRANSLATION
60 #endif
61 
63 
64 @implementation QT_MANGLE_NAMESPACE(QCocoaMenuLoader)
65 
66 - (void)awakeFromNib
67 {
68  servicesItem = [[appMenu itemWithTitle:@"Services"] retain];
69  hideAllOthersItem = [[appMenu itemWithTitle:@"Hide Others"] retain];
70  showAllItem = [[appMenu itemWithTitle:@"Show All"] retain];
71 
72  // Get the names in the nib to match the app name set by Qt.
73  const NSString *appName = reinterpret_cast<const NSString*>(QCFString::toCFStringRef(qAppName()));
74  [quitItem setTitle:[[quitItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
75  withString:const_cast<NSString *>(appName)]];
76  [hideItem setTitle:[[hideItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
77  withString:const_cast<NSString *>(appName)]];
78  [aboutItem setTitle:[[aboutItem title] stringByReplacingOccurrencesOfString:@"NewApplication"
79  withString:const_cast<NSString *>(appName)]];
80  [appName release];
81  // Disable the items that don't do anything. If someone associates a QAction with them
82  // They should get synced back in.
83  [preferencesItem setEnabled:NO];
84  [preferencesItem setHidden:YES];
85  [aboutItem setEnabled:NO];
86  [aboutItem setHidden:YES];
87 }
88 
89 - (void)ensureAppMenuInMenu:(NSMenu *)menu
90 {
91  // The application menu is the menu in the menu bar that contains the
92  // 'Quit' item. When changing menu bar (e.g when switching between
93  // windows with different menu bars), we never recreate this menu, but
94  // instead pull it out the current menu bar and place into the new one:
95  NSMenu *mainMenu = [NSApp mainMenu];
96  if ([NSApp mainMenu] == menu)
97  return; // nothing to do (menu is the current menu bar)!
98 
99 #ifndef QT_NAMESPACE
100  Q_ASSERT(mainMenu);
101 #endif
102  // Grab the app menu out of the current menu.
103  int numItems = [mainMenu numberOfItems];
104  NSMenuItem *oldAppMenuItem = 0;
105  for (int i = 0; i < numItems; ++i) {
106  NSMenuItem *item = [mainMenu itemAtIndex:i];
107  if ([item submenu] == appMenu) {
108  oldAppMenuItem = item;
109  [oldAppMenuItem retain];
110  [mainMenu removeItemAtIndex:i];
111  break;
112  }
113  }
114 
115  if (oldAppMenuItem) {
116  [oldAppMenuItem setSubmenu:nil];
117  [oldAppMenuItem release];
118  NSMenuItem *appMenuItem = [[NSMenuItem alloc] initWithTitle:@"Apple"
119  action:nil keyEquivalent:@""];
120  [appMenuItem setSubmenu:appMenu];
121  [menu insertItem:appMenuItem atIndex:0];
122  }
123 }
124 
125 - (void)removeActionsFromAppMenu
126 {
127  for (NSMenuItem *item in [appMenu itemArray])
128  [item setTag:nil];
129 }
130 
131 - (void)dealloc
132 {
133  [servicesItem release];
134  [hideAllOthersItem release];
135  [showAllItem release];
136 
137  [lastAppSpecificItem release];
138  [theMenu release];
139  [appMenu release];
140  [super dealloc];
141 }
142 
143 - (NSMenu *)menu
144 {
145  return [[theMenu retain] autorelease];
146 }
147 
148 - (NSMenu *)applicationMenu
149 {
150  return [[appMenu retain] autorelease];
151 }
152 
153 - (NSMenuItem *)quitMenuItem
154 {
155  return [[quitItem retain] autorelease];
156 }
157 
158 - (NSMenuItem *)preferencesMenuItem
159 {
160  return [[preferencesItem retain] autorelease];
161 }
162 
163 - (NSMenuItem *)aboutMenuItem
164 {
165  return [[aboutItem retain] autorelease];
166 }
167 
168 - (NSMenuItem *)aboutQtMenuItem
169 {
170  return [[aboutQtItem retain] autorelease];
171 }
172 
173 - (NSMenuItem *)hideMenuItem
174 {
175  return [[hideItem retain] autorelease];
176 }
177 
178 - (NSMenuItem *)appSpecificMenuItem
179 {
180  // Create an App-Specific menu item, insert it into the menu and return
181  // it as an autorelease item.
182  NSMenuItem *item = [[NSMenuItem alloc] init];
183 
184  NSInteger location;
185  if (lastAppSpecificItem == nil) {
186  location = [appMenu indexOfItem:aboutQtItem];
187  } else {
188  location = [appMenu indexOfItem:lastAppSpecificItem];
189  [lastAppSpecificItem release];
190  }
191  lastAppSpecificItem = item; // Keep track of this for later (i.e., don't release it)
192  [appMenu insertItem:item atIndex:location + 1];
193 
194  return [[item retain] autorelease];
195 }
196 
197 - (BOOL) acceptsFirstResponder
198 {
199  return YES;
200 }
201 
202 - (void)terminate:(id)sender
203 {
204  [NSApp terminate:sender];
205 }
206 
207 - (void)orderFrontStandardAboutPanel:(id)sender
208 {
209  [NSApp orderFrontStandardAboutPanel:sender];
210 }
211 
212 - (void)hideOtherApplications:(id)sender
213 {
214  [NSApp hideOtherApplications:sender];
215 }
216 
217 - (void)unhideAllApplications:(id)sender
218 {
219  [NSApp unhideAllApplications:sender];
220 }
221 
222 - (void)hide:(id)sender
223 {
224  [NSApp hide:sender];
225 }
226 
227 - (void)qtUpdateMenubar
228 {
230 }
231 
232 - (void)qtTranslateApplicationMenu
233 {
234 #ifndef QT_NO_TRANSLATION
235  [servicesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(0))];
236  [hideItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(1).arg(qAppName()))];
237  [hideAllOthersItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(2))];
238  [showAllItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(3))];
239  [preferencesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(4))];
240  [quitItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(5).arg(qAppName()))];
241  [aboutItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(6).arg(qAppName()))];
242 #endif
243 }
244 
245 - (IBAction)qtDispatcherToQAction:(id)sender
246 {
247  QScopedLoopLevelCounter loopLevelCounter(QApplicationPrivate::instance()->threadData);
248  NSMenuItem *item = static_cast<NSMenuItem *>(sender);
249  if (QAction *action = reinterpret_cast<QAction *>([item tag])) {
250  action->trigger();
251  } else if (item == quitItem) {
252  // We got here because someone was once the quitItem, but it has been
253  // abandoned (e.g., the menubar was deleted). In the meantime, just do
254  // normal QApplication::quit().
255  qApp->quit();
256  }
257 }
258 
259  - (void)orderFrontCharacterPalette:(id)sender
260  {
261  [NSApp orderFrontCharacterPalette:sender];
262  }
263 
264 - (BOOL)validateMenuItem:(NSMenuItem*)menuItem
265 {
266  if ([menuItem action] == @selector(hide:)
267  || [menuItem action] == @selector(hideOtherApplications:)
268  || [menuItem action] == @selector(unhideAllApplications:)) {
269  return [NSApp validateMenuItem:menuItem];
270  } else {
271  return [menuItem isEnabled];
272  }
273 }
274 
275 @end
276 #endif // QT_MAC_USE_COCOA
int type
Definition: qmetatype.cpp:239
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static CFStringRef toCFStringRef(const QString &str)
Definition: qcore_mac.cpp:69
static QApplicationPrivate * instance()
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QString qAppName()
void NSMenuItem
Definition: qmenu_p.h:80
#define QT_FORWARD_DECLARE_CLASS(name)
Definition: qglobal.h:95
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QString qt_mac_applicationmenu_string(int type)
em>Reimplemented Function
#define qApp
static bool macUpdateMenuBarImmediatly()
Definition: qmenu_mac.mm:2066
static QTestResult::TestLocation location
Definition: qtestresult.cpp:63
#define QT_USE_NAMESPACE
This macro expands to using QT_NAMESPACE if QT_NAMESPACE is defined and nothing otherwise.
Definition: qglobal.h:88
static QString appName
The QAction class provides an abstract user interface action that can be inserted into widgets...
Definition: qaction.h:64