summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2007-10-09 14:17:04 +0000
committerKurt Zenker <kz@openoffice.org>2007-10-09 14:17:04 +0000
commit8f6f151ad251a967452cba47f9f4a3d8b49d1e1f (patch)
tree2aa32f29a6f0095d582fa813f5cc600fd52a2750 /vcl
parent3ca29c20afd167d7e013d1b3ffc361e99dae4d8f (diff)
INTEGRATION: CWS aquavcl03 (1.2.4); FILE MERGED
2007/10/01 13:45:55 pl 1.2.4.14: #i80230# shortcut forwarding with native menus, preparations for menu disabling in modal case 2007/09/27 13:58:42 pl 1.2.4.13: remove unused headers 2007/09/27 13:09:49 pl 1.2.4.12: #i80407# preliminary code to set the app name in the menu 2007/09/24 16:29:35 pl 1.2.4.11: #i80230# fix some leaks 2007/09/18 11:37:53 pl 1.2.4.10: #i80695# protect against calling dead objects 2007/09/10 07:28:44 ericb 1.2.4.9: #i81404# a try to fix SalNSMenuItem leaks + make code more robust against potential crashes 2007/09/06 15:43:13 pl 1.2.4.8: #i80230# prevent menuitem triggered while modal dialogs are opened 2007/08/08 16:07:13 pl 1.2.4.7: #i80230# enable app menu entries about an preferences again 2007/08/07 10:33:24 pl 1.2.4.6: RESYNC: (1.2-1.3); FILE MERGED 2007/08/06 17:04:00 pl 1.2.4.5: #i80230# try a solution for the multiple supermenu problem 2007/08/02 17:48:42 pl 1.2.4.4: #i80230# menu cleanup 2007/08/01 17:54:13 pl 1.2.4.3: #i80230# multiple documents 2007/08/01 15:26:43 pl 1.2.4.2: #i80230# life cycle of menus and menuitems 2007/07/31 19:40:38 pl 1.2.4.1: #i80230# move AquaSalMenu/AquaSalMenuItem to Cocoa
Diffstat (limited to 'vcl')
-rw-r--r--vcl/aqua/source/window/salmenu.cxx574
1 files changed, 400 insertions, 174 deletions
diff --git a/vcl/aqua/source/window/salmenu.cxx b/vcl/aqua/source/window/salmenu.cxx
index bbc41a8e5158..4367c30f51ce 100644
--- a/vcl/aqua/source/window/salmenu.cxx
+++ b/vcl/aqua/source/window/salmenu.cxx
@@ -4,9 +4,9 @@
*
* $RCSfile: salmenu.cxx,v $
*
- * $Revision: 1.4 $
+ * $Revision: 1.5 $
*
- * last change: $Author: ihi $ $Date: 2007-09-13 16:32:05 $
+ * last change: $Author: kz $ $Date: 2007-10-09 15:17:04 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -33,50 +33,140 @@
*
************************************************************************/
-#include <saldata.hxx>
-#include <salinst.h>
-#include <salmenu.h>
-#include <vcl/impbmp.hxx>
-#include <vcl/svids.hrc>
+#include "saldata.hxx"
+#include "salinst.h"
+#include "salmenu.h"
+#include "salframe.h"
+#include "vcl/svids.hrc"
+#include "vcl/cmdevt.hxx"
+#include "vcl/window.hxx"
+#include "rtl/ustrbuf.hxx"
+const AquaSalMenu* AquaSalMenu::pCurrentMenuBar = NULL;
-// nPos is 0 based, MenuItemIndex is 1 based
-#define GETITEMINDEXBYPOS(nPos) (nPos+1)
+@interface MainMenuSelector : NSObject
+{
+}
+-(void)showDialog: (int)nDialog;
+-(void)showPreferences: (id)sender;
+-(void)showAbout: (id)sender;
+@end
-// =======================================================================
+@implementation MainMenuSelector
+-(void)showDialog: (int)nDialog
+{
+ if( AquaSalMenu::pCurrentMenuBar )
+ {
+ const AquaSalFrame* pFrame = AquaSalMenu::pCurrentMenuBar->mpFrame;
+ if( pFrame && AquaSalFrame::isAlive( pFrame ) )
+ {
+ pFrame->CallCallback( SALEVENT_SHOWDIALOG, reinterpret_cast<void*>(nDialog) );
+ }
+ }
+}
-SalMenu* AquaSalInstance::CreateMenu( BOOL bMenuBar )
+-(void)showPreferences: (id) sender
{
- AquaSalMenu *pAquaSalMenu = new AquaSalMenu();
- static MenuID inMenuID=0;
+ [self showDialog: SHOWDIALOG_ID_PREFERENCES];
+}
+-(void)showAbout: (id) sender
+{
+ [self showDialog: SHOWDIALOG_ID_ABOUT];
+}
+@end
- pAquaSalMenu->mbMenuBar = bMenuBar;
+// FIXME: currently this is leaked
+static MainMenuSelector* pMainMenuSelector = nil;
- CreateNewMenu (inMenuID++, 0, &pAquaSalMenu->mrMenuRef);
+// =======================================================================
- /* Associate the pointer to this SalMenu with the menu */
- SetMenuItemProperty (pAquaSalMenu->mrMenuRef, 0,
- APP_PROPERTY_CREATOR, APP_PROPERTY_TAG_MENU_POINTER,
- sizeof(pAquaSalMenu), &pAquaSalMenu);
+SalMenu* AquaSalInstance::CreateMenu( BOOL bMenuBar )
+{
+ AquaSalMenu *pAquaSalMenu = new AquaSalMenu( bMenuBar );
static bool bOnce = true;
if( bOnce )
{
bOnce = false;
- EnableMenuCommand(NULL, kHICommandPreferences); // enable pref menu
ResMgr* pMgr = ImplGetResMgr();
if( pMgr )
{
- String aAbout( ResId( SV_STDTEXT_ABOUT, *pMgr ) );
- MenuRef rApplicationMenu;
- MenuItemIndex outIndex[1];
- GetIndMenuItemWithCommandID(NULL, kHICommandPreferences, 1, &rApplicationMenu, outIndex);
- CFStringRef rStr = CreateCFString( aAbout );
- if ( rStr )
+ // get the main menu
+ NSMenu* pMainMenu = [NSApp mainMenu];
+ if( pMainMenu != nil )
{
- InsertMenuItemTextWithCFString(rApplicationMenu, rStr, (short) 0, 0, kHICommandAbout);
- CFRelease( rStr );
+ // create the action selector
+ pMainMenuSelector = [[MainMenuSelector alloc] init];
+
+ // get the proper submenu
+ NSMenu* pAppMenu = [[pMainMenu itemAtIndex: 0] submenu];
+ if( pAppMenu )
+ {
+ // insert about entry
+ String aAbout( ResId( SV_STDTEXT_ABOUT, *pMgr ) );
+ NSString* pString = CreateNSString( aAbout );
+ NSMenuItem* pNewItem = [pAppMenu insertItemWithTitle: pString
+ action: @selector(showAbout:)
+ keyEquivalent: @""
+ atIndex: 0];
+ if (pString)
+ [pString release];
+ if( pNewItem )
+ {
+ [pNewItem setTarget: pMainMenuSelector];
+ [pAppMenu insertItem: [NSMenuItem separatorItem] atIndex: 1];
+ }
+
+ // insert preferences entry
+ String aPref( ResId( SV_STDTEXT_PREFERENCES, *pMgr ) );
+ pString = CreateNSString( aPref );
+ pNewItem = [pAppMenu insertItemWithTitle: pString
+ action: @selector(showPreferences:)
+ keyEquivalent: @","
+ atIndex: 2];
+ if (pString)
+ [pString release];
+ if( pNewItem )
+ {
+ [pNewItem setKeyEquivalentModifierMask: NSCommandKeyMask];
+ [pNewItem setTarget: pMainMenuSelector];
+ [pAppMenu insertItem: [NSMenuItem separatorItem] atIndex: 3];
+ }
+
+
+ // FIXME: there probably is a more canonical way to set the string
+ // in the application menu
+
+ // replace instances of "NewApplication" (artifact from out .nib)
+ // by the application name
+
+ // get the application name
+ ResHookProc pProc = ResMgr::GetReadStringHook();
+ String aAppName( RTL_CONSTASCII_USTRINGPARAM( "%PRODUCTNAME" ) );
+ if( pProc )
+ pProc( aAppName );
+
+ int nItems = [pAppMenu numberOfItems];
+ for( int i = 4; i < nItems; i++ )
+ {
+ NSMenuItem* pItem = [pAppMenu itemAtIndex: i];
+ if( pItem != nil )
+ {
+ OUString aTitle( GetOUString( [pItem title] ) );
+ sal_Int32 nInd = aTitle.indexOfAsciiL( "NewApplication", 14 );
+ if( nInd != -1 )
+ {
+ rtl::OUStringBuffer aBuf( aTitle.getLength()*2 );
+ aBuf.append( aTitle.copy( 0, nInd ) );
+ aBuf.append( aAppName );
+ if( aTitle.getLength() > nInd + 14 )
+ aBuf.append( aTitle.copy( nInd+14, aTitle.getLength() - nInd - 14 ) );
+ [pItem setTitle: [CreateNSString( aBuf.makeStringAndClear() ) autorelease]];
+ }
+ }
+ }
+ }
}
}
}
@@ -85,11 +175,6 @@ SalMenu* AquaSalInstance::CreateMenu( BOOL bMenuBar )
void AquaSalInstance::DestroyMenu( SalMenu* pSalMenu )
{
-
- AquaSalMenu *pAquaSalMenu = (AquaSalMenu *) pSalMenu;
-
- RemoveMenuItemProperty (pAquaSalMenu->mrMenuRef, 0,
- APP_PROPERTY_CREATOR, APP_PROPERTY_TAG_MENU_POINTER);
delete pSalMenu;
}
@@ -98,20 +183,7 @@ SalMenuItem* AquaSalInstance::CreateMenuItem( const SalItemParams* pItemData )
if( !pItemData )
return NULL;
- AquaSalMenuItem *pSalMenuItem = new AquaSalMenuItem();
-
- pSalMenuItem->maMenuAttributes = 0;
- pSalMenuItem->mpSubMenu = NULL;
- pSalMenuItem->mnId = pItemData->nId;
- pSalMenuItem->mText = pItemData->aText;
-
- // Delete mnemonics
- pSalMenuItem->mText.EraseAllChars( '~' );
-
- pSalMenuItem->mpMenu = pItemData->pMenu;
-
- if (pItemData->eType == MENUITEM_SEPARATOR)
- pSalMenuItem->maMenuAttributes |= kMenuItemAttrSeparator;
+ AquaSalMenuItem *pSalMenuItem = new AquaSalMenuItem( pItemData );
return pSalMenuItem;
}
@@ -129,11 +201,94 @@ void AquaSalInstance::DestroyMenuItem( SalMenuItem* pSalMenuItem )
* AquaSalMenu
*/
+AquaSalMenu::AquaSalMenu( bool bMenuBar ) :
+ mbMenuBar( bMenuBar ),
+ mpMenu( nil ),
+ mpVCLMenu( NULL ),
+ mpFrame( NULL ),
+ mpParentSalMenu( NULL )
+{
+ if( ! mbMenuBar )
+ {
+ mpMenu = [[SalNSMenu alloc] initWithMenu: this];
+ [mpMenu setDelegate: mpMenu];
+ }
+ else
+ {
+ mpMenu = [NSApp mainMenu];
+ }
+ [mpMenu setAutoenablesItems: NO];
+}
+
AquaSalMenu::~AquaSalMenu()
{
- if (this->mrMenuRef)
+ // is this leaking in some cases ? the release often leads to a duplicate release
+ // it seems the parent item gets ownership of the menu
+ if( mpMenu && ! mbMenuBar )
+ {
+ // the system may still hold a reference on mpMenu
+ // so set the pointer to this AquaSalMenu to NULL
+ // to protect from calling a dead object
+
+ // in ! mbMenuBar case our mpMenu is actually a SalNSMenu*
+ // so we can safely cast here
+ [static_cast<SalNSMenu*>(mpMenu) setSalMenu: NULL];
+ [mpMenu release];
+ }
+}
+
+int AquaSalMenu::getItemIndexByPos( USHORT nPos ) const
+{
+ int nIndex = 0;
+ if( nPos == MENU_APPEND )
+ nIndex = [mpMenu numberOfItems];
+ else
+ nIndex = sal::static_int_cast<int>( mbMenuBar ? nPos+1 : nPos );
+ return nIndex;
+}
+
+const AquaSalFrame* AquaSalMenu::getFrame() const
+{
+ const AquaSalMenu* pMenu = this;
+ while( pMenu && ! pMenu->mpFrame )
+ pMenu = pMenu->mpParentSalMenu;
+ return pMenu ? pMenu->mpFrame : NULL;
+}
+
+void AquaSalMenu::setMainMenu()
+{
+ DBG_ASSERT( mbMenuBar, "setMainMenu on non menubar" );
+ if( mbMenuBar )
{
- DisposeMenu(this->mrMenuRef);
+ if( pCurrentMenuBar != this )
+ {
+ // remove items from main menu
+ for( int nItems = [mpMenu numberOfItems]; nItems > 1; nItems-- )
+ [mpMenu removeItemAtIndex: 1];
+ // insert our items
+ for( unsigned int i = 0; i < maItems.size(); i++ )
+ {
+ NSMenuItem* pItem = maItems[i]->mpMenuItem;
+ [mpMenu insertItem: pItem atIndex: i+1];
+ }
+ pCurrentMenuBar = this;
+ }
+ enableMainMenu( true );
+ }
+}
+
+void AquaSalMenu::enableMainMenu( bool bEnable )
+{
+ NSMenu* pMainMenu = [NSApp mainMenu];
+ if( pMainMenu )
+ {
+ // enable/disable items from main menu
+ int nItems = [pMainMenu numberOfItems];
+ for( int n = 1; n < nItems; n++ )
+ {
+ NSMenuItem* pItem = [pMainMenu itemAtIndex: n];
+ [pItem setEnabled: bEnable ? YES : NO];
+ }
}
}
@@ -155,112 +310,94 @@ BOOL AquaSalMenu::VisibleMenuBar()
void AquaSalMenu::SetFrame( const SalFrame *pFrame )
{
- AquaLog( ">*>_> %s\n",__func__);
+ mpFrame = static_cast<const AquaSalFrame*>(pFrame);
}
void AquaSalMenu::InsertItem( SalMenuItem* pSalMenuItem, unsigned nPos )
{
- AquaSalMenuItem *pAquaSalMenuItem = (AquaSalMenuItem *) pSalMenuItem;
-
- // save MenuRef of the menu for future reference
- pAquaSalMenuItem->mrParentMenuRef = mrMenuRef;
-
- if (mbMenuBar)
- AppendMenuItemTextWithCFString( mrMenuRef, NULL, pAquaSalMenuItem->maMenuAttributes, 0, &pAquaSalMenuItem->mnMenuItemIndex);
+ AquaSalMenuItem *pAquaSalMenuItem = static_cast<AquaSalMenuItem*>(pSalMenuItem);
+ pAquaSalMenuItem->mpParentMenu = this;
+ DBG_ASSERT( pAquaSalMenuItem->mpVCLMenu == NULL ||
+ pAquaSalMenuItem->mpVCLMenu == mpVCLMenu ||
+ mpVCLMenu == NULL,
+ "resetting menu ?" );
+ if( pAquaSalMenuItem->mpVCLMenu )
+ mpVCLMenu = pAquaSalMenuItem->mpVCLMenu;
+
+ if( nPos == MENU_APPEND || nPos == maItems.size() )
+ maItems.push_back( pAquaSalMenuItem );
+ else if( nPos < maItems.size() )
+ maItems.insert( maItems.begin() + nPos, pAquaSalMenuItem );
else
- {
- CFStringRef menuText = CreateCFString(pAquaSalMenuItem->mText);
- if ( menuText )
- {
- AppendMenuItemTextWithCFString( mrMenuRef, menuText, pAquaSalMenuItem->maMenuAttributes, 0, &pAquaSalMenuItem->mnMenuItemIndex);
- CFRelease(menuText);
- }
- }
+ DBG_ERROR( "invalid item index in insert" );
- /* Associate the pointer to this SalMenuItem with the menu item */
- SetMenuItemProperty (mrMenuRef, pAquaSalMenuItem->mnMenuItemIndex,
- APP_PROPERTY_CREATOR, APP_PROPERTY_TAG_MENU_ITEM_POINTER,
- sizeof(pSalMenuItem), &pSalMenuItem);
+ if( ! mbMenuBar || pCurrentMenuBar == this )
+ [mpMenu insertItem: pAquaSalMenuItem->mpMenuItem atIndex: getItemIndexByPos(nPos)];
}
void AquaSalMenu::RemoveItem( unsigned nPos )
{
- if (mrMenuRef)
- DeleteMenuItem (mrMenuRef, GETITEMINDEXBYPOS(nPos));
+ if( nPos == MENU_APPEND )
+ maItems.pop_back();
+ else if( nPos < maItems.size() )
+ maItems.erase( maItems.begin()+nPos );
+ else
+ DBG_ERROR( "invalid item index in remove" );
+ if( ! mbMenuBar || pCurrentMenuBar == this )
+ [mpMenu removeItemAtIndex: getItemIndexByPos(nPos)];
}
void AquaSalMenu::SetSubMenu( SalMenuItem* pSalMenuItem, SalMenu* pSubMenu, unsigned nPos )
{
- AquaSalMenuItem *pAquaSalMenuItem = (AquaSalMenuItem *) pSalMenuItem;
-
- AquaSalMenu *subAquaSalMenu = (AquaSalMenu *) pSubMenu;
+ AquaSalMenuItem *pAquaSalMenuItem = static_cast<AquaSalMenuItem*>(pSalMenuItem);
+ AquaSalMenu *subAquaSalMenu = static_cast<AquaSalMenu*>(pSubMenu);
// FIXME: in svtools - workben - svdem, pSubMenu is NULL!
if (subAquaSalMenu)
{
- CFStringRef menuText = CreateCFString(pAquaSalMenuItem->mText);
- if ( menuText )
+ pAquaSalMenuItem->mpSubMenu = subAquaSalMenu;
+ if( subAquaSalMenu->mpParentSalMenu == NULL )
{
- pAquaSalMenuItem->mpSubMenu = pSubMenu;
- SetMenuTitleWithCFString(subAquaSalMenu->mrMenuRef, menuText);
- CFRelease(menuText);
+ subAquaSalMenu->mpParentSalMenu = this;
+ [pAquaSalMenuItem->mpMenuItem setSubmenu: subAquaSalMenu->mpMenu];
+
+ // set title of submenu
+ [subAquaSalMenu->mpMenu setTitle: [pAquaSalMenuItem->mpMenuItem title]];
+ }
+ else if( subAquaSalMenu->mpParentSalMenu != this )
+ {
+ // cocoa doesn't allow menus to be submenus of multiple
+ // menu items, so place a copy in the menu item instead ?
+ // let's hope that NSMenu copy does the right thing
+ NSMenu* pCopy = [subAquaSalMenu->mpMenu copy];
+ [pAquaSalMenuItem->mpMenuItem setSubmenu: pCopy];
+
+ // set title of submenu
+ [pCopy setTitle: [pAquaSalMenuItem->mpMenuItem title]];
}
- SetMenuItemHierarchicalMenu (mrMenuRef, pAquaSalMenuItem->mnMenuItemIndex, subAquaSalMenu->mrMenuRef);
}
}
void AquaSalMenu::CheckItem( unsigned nPos, BOOL bCheck )
{
- CheckMenuItem(this->mrMenuRef, GETITEMINDEXBYPOS(nPos), bCheck);
+ if( nPos < maItems.size() )
+ {
+ NSMenuItem* pItem = maItems[nPos]->mpMenuItem;
+ [pItem setState: bCheck ? NSOnState : NSOffState];
+ }
}
void AquaSalMenu::EnableItem( unsigned nPos, BOOL bEnable )
{
- if (bEnable)
- EnableMenuItem(this->mrMenuRef, GETITEMINDEXBYPOS(nPos));
- else
- DisableMenuItem(this->mrMenuRef, GETITEMINDEXBYPOS(nPos));
+ if( nPos < maItems.size() )
+ {
+ NSMenuItem* pItem = maItems[nPos]->mpMenuItem;
+ [pItem setEnabled: bEnable ? YES : NO];
+ }
}
void AquaSalMenu::SetItemImage( unsigned nPos, SalMenuItem* pSalMenuItem, const Image& rImage )
{
- AquaLog( ">*>_> %s\n",__func__);
-
- if (!pSalMenuItem)
- return;
-
- AquaSalMenuItem *pAquaSalMenuItem = static_cast<AquaSalMenuItem *>(pSalMenuItem);
-
- BitmapEx aBitmapEx = rImage.GetBitmapEx();
- aBitmapEx.Mirror(BMP_MIRROR_VERT);
-
- pAquaSalMenuItem->maBitmap = aBitmapEx.GetBitmap();
-
- Bitmap aBitmap (pAquaSalMenuItem->maBitmap);
-
- ImpBitmap *aImpBitmap = aBitmap.ImplGetImpBitmap();
-
- if (aImpBitmap)
- {
- AquaSalBitmap *pSalBmp = static_cast<AquaSalBitmap *>(aImpBitmap->ImplGetSalBitmap());
- CGImageRef xImage = NULL;
-
- // check alpha
- if (aBitmapEx.IsAlpha())
- {
- AquaSalBitmap *pSalMask = static_cast<AquaSalBitmap *>(aBitmapEx.GetAlpha().GetBitmap().ImplGetImpBitmap()->ImplGetSalBitmap());
-
- if (pSalMask)
- xImage = pSalBmp->CreateWithMask ( *pSalMask, 0, 0, pSalBmp->mnWidth, pSalBmp->mnHeight);
- }
-
- if (!xImage)
- xImage = pSalBmp->CreateCroppedImage( 0, 0, pSalBmp->mnWidth, pSalBmp->mnHeight );
-
- SetMenuItemIconHandle(mrMenuRef, pAquaSalMenuItem->mnMenuItemIndex, kMenuCGImageRefType, (Handle)xImage);
-
- CGImageRelease(xImage);
- }
}
void AquaSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const XubString& rText )
@@ -270,50 +407,40 @@ void AquaSalMenu::SetItemText( unsigned nPos, SalMenuItem* pSalMenuItem, const X
AquaSalMenuItem *pAquaSalMenuItem = (AquaSalMenuItem *) pSalMenuItem;
- pAquaSalMenuItem->mText = rText;
+ String aText( rText );
// Delete mnemonics
- pAquaSalMenuItem->mText.EraseAllChars( '~' );
-
- CFStringRef menuText = CreateCFString(pAquaSalMenuItem->mText);
- if ( menuText )
- {
- SetMenuItemTextWithCFString( mrMenuRef, pAquaSalMenuItem->mnMenuItemIndex, menuText);
-
- // if the menu item has a submenu, change its title as well
- if (pAquaSalMenuItem->mpSubMenu)
- {
- AquaSalMenu *subMenu = (AquaSalMenu *) pAquaSalMenuItem->mpSubMenu;
- SetMenuTitleWithCFString(subMenu->mrMenuRef, menuText);
- }
- CFRelease(menuText);
- }
+ aText.EraseAllChars( '~' );
+
+ NSString* pString = CreateNSString( aText );
+ [pAquaSalMenuItem->mpMenuItem setTitle: pString];
+ // if the menu item has a submenu, change its title as well
+ if (pAquaSalMenuItem->mpSubMenu)
+ [pAquaSalMenuItem->mpSubMenu->mpMenu setTitle: pString];
+ if (pString)
+ [pString release];
}
void AquaSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, const KeyCode& rKeyCode, const XubString& rKeyName )
{
- AquaLog( ">*>_> %s\n",__func__);
-
USHORT nModifier;
- int nCommandKey = -1, nKeyGlyph = -1;
+ sal_Unicode nCommandKey = 0;
- if (rKeyCode.GetCode())
+ USHORT nKeyCode=rKeyCode.GetCode();
+ if( nKeyCode )
{
- USHORT nKeyCode=rKeyCode.GetCode();
-
if ((nKeyCode>=KEY_A) && (nKeyCode<=KEY_Z)) // letter A..Z
- nCommandKey=nKeyCode-KEY_A+'A';
+ nCommandKey = nKeyCode-KEY_A + 'a';
else if ((nKeyCode>=KEY_0) && (nKeyCode<=KEY_9)) // numbers 0..9
- nCommandKey=nKeyCode-KEY_0+'0';
- else if ((nKeyCode>=KEY_F1) && (nKeyCode<=KEY_F12)) // function keys F1..F12
- nKeyGlyph=kMenuF1Glyph+nKeyCode-KEY_F1; // only for n<13!
- else if ((nKeyCode>=KEY_F13) && (nKeyCode<=KEY_F15))
- nKeyGlyph=kMenuF13Glyph+nKeyCode-KEY_F13; // function keys F13, F14, F15
-#if 0
- else if (nKeyCode==KEY_SPACE)
- nKeyGlyph=kMenuSpaceGlyph;
-#endif
+ nCommandKey = nKeyCode-KEY_0 + '0';
+ else if ((nKeyCode>=KEY_F1) && (nKeyCode<=KEY_F26)) // function keys F1..F26
+ nCommandKey = nKeyCode-KEY_F1 + NSF1FunctionKey;
+ else if( nKeyCode == KEY_REPEAT )
+ nCommandKey = NSRedoFunctionKey;
+ else if( nKeyCode == KEY_SPACE )
+ nCommandKey = ' ';
else
+ {
switch (nKeyCode)
{
case KEY_ADD:
@@ -341,41 +468,44 @@ void AquaSalMenu::SetAccelerator( unsigned nPos, SalMenuItem* pSalMenuItem, cons
nCommandKey='=';
break;
}
-
- if (nCommandKey > -1)
- SetMenuItemCommandKey (mrMenuRef, GETITEMINDEXBYPOS(nPos), 0, nCommandKey);
-
- if (nKeyGlyph > -1)
- SetMenuItemKeyGlyph (mrMenuRef, GETITEMINDEXBYPOS(nPos), nKeyGlyph);
-
- if((nKeyGlyph <= -1) && (nCommandKey <= -1))
- AquaLog( "%s: Couldn't process rKeyCode.GetCode()=%d\n",__func__, rKeyCode.GetCode());
+ }
}
+ else // not even a code ? nonsense -> ignore
+ return;
+
+ DBG_ASSERT( nCommandKey, "unmapped accelerator key" );
nModifier=rKeyCode.GetAllModifier();
- int nItemModifier = kMenuNoCommandModifier;
+ // should always use the command key
+ int nItemModifier = NSCommandKeyMask;
+ // ignore KEY_MOD1, Ctrl replaced by Command
+ #if 0
if (nModifier & KEY_MOD1)
- nItemModifier = kMenuNoModifiers; // for the cmd key
- // = and not += because should replace kMenuNoCommandModifier
+ nItemModifier |= NSControlKeyMask; // for the Ctrl key
+ #endif
if (nModifier & KEY_SHIFT)
- nItemModifier += kMenuShiftModifier;
-
- if (nModifier & KEY_MOD5)
- //should use mod3 or 2
- nItemModifier += kMenuOptionModifier; // for the ALT key
+ {
+ nItemModifier |= NSShiftKeyMask; // actually useful only for function keys
+ if( nKeyCode >= KEY_A && nKeyCode <= KEY_Z )
+ nCommandKey = nKeyCode - KEY_A + 'A';
+ }
if(nModifier & KEY_MOD2)
- nItemModifier += kMenuControlModifier; // maybe for the ctrl key
+ nItemModifier |= NSAlternateKeyMask;
- SetMenuItemModifiers (mrMenuRef, GETITEMINDEXBYPOS(nPos), nItemModifier);
+ AquaSalMenuItem *pAquaSalMenuItem = (AquaSalMenuItem *) pSalMenuItem;
+ NSString* pString = CreateNSString( rtl::OUString( &nCommandKey, 1 ) );
+ [pAquaSalMenuItem->mpMenuItem setKeyEquivalent: pString];
+ [pAquaSalMenuItem->mpMenuItem setKeyEquivalentModifierMask: nItemModifier];
+ if (pString)
+ [pString release];
}
void AquaSalMenu::GetSystemMenuData( SystemMenuData* pData )
{
- AquaLog( ">*>_> %s\n",__func__);
}
// =======================================================================
@@ -384,8 +514,104 @@ void AquaSalMenu::GetSystemMenuData( SystemMenuData* pData )
* SalMenuItem
*/
+AquaSalMenuItem::AquaSalMenuItem( const SalItemParams* pItemData ) :
+ mnId( pItemData->nId ),
+ mpVCLMenu( pItemData->pMenu ),
+ mpParentMenu( NULL ),
+ mpSubMenu( NULL ),
+ mpMenuItem( nil )
+{
+ String aText( pItemData->aText );
+
+ // Delete mnemonics
+ aText.EraseAllChars( '~' );
+
+ if (pItemData->eType == MENUITEM_SEPARATOR)
+ {
+ mpMenuItem = [NSMenuItem separatorItem];
+ // these can go occasionally go in and out of a menu, ensure their lifecycle
+ // also for the release in AquaSalMenuItem destructor
+ [mpMenuItem retain];
+ }
+ else
+ {
+ mpMenuItem = [[SalNSMenuItem alloc] initWithMenuItem: this];
+ [mpMenuItem setEnabled: YES];
+ NSString* pString = CreateNSString( aText );
+ [mpMenuItem setTitle: pString];
+ if (pString)
+ [pString release];
+
+ // anything but a separator should set a menu to dispatch to
+ DBG_ASSERT( mpVCLMenu, "no menu" );
+ }
+}
+
AquaSalMenuItem::~AquaSalMenuItem()
{
+ if( mpMenuItem )
+ [mpMenuItem release];
}
// -------------------------------------------------------------------
+
+@implementation SalNSMenu
+-(id)initWithMenu: (AquaSalMenu*)pMenu
+{
+ mpMenu = pMenu;
+ return [super initWithTitle: [NSString string]];
+}
+
+-(void)menuNeedsUpdate: (NSMenu*)pMenu
+{
+ YIELD_GUARD;
+
+ if( mpMenu )
+ {
+ const AquaSalFrame* pFrame = mpMenu->getFrame();
+ if( pFrame && AquaSalFrame::isAlive( pFrame ) )
+ {
+ SalMenuEvent aMenuEvt;
+ aMenuEvt.mnId = 0;
+ aMenuEvt.mpMenu = mpMenu->mpVCLMenu;
+ if( aMenuEvt.mpMenu )
+ {
+ pFrame->CallCallback(SALEVENT_MENUACTIVATE, &aMenuEvt);
+ pFrame->CallCallback(SALEVENT_MENUDEACTIVATE, &aMenuEvt);
+ }
+ else
+ DBG_ERROR( "unconnected menu" );
+ }
+ }
+}
+
+-(void)setSalMenu: (AquaSalMenu*)pMenu
+{
+ mpMenu = pMenu;
+}
+@end
+
+@implementation SalNSMenuItem
+-(id)initWithMenuItem: (AquaSalMenuItem*)pMenuItem
+{
+ mpMenuItem = pMenuItem;
+ id ret = [super initWithTitle: [NSString string] action: nil keyEquivalent: [NSString string]];
+ [ret setAction:@selector(menuItemTriggered:)];
+ [ret setTarget: self];
+ return ret;
+}
+-(void)menuItemTriggered: (id)aSender
+{
+ YIELD_GUARD;
+
+ const AquaSalFrame* pFrame = mpMenuItem->mpParentMenu ? mpMenuItem->mpParentMenu->getFrame() : NULL;
+ if( pFrame && AquaSalFrame::isAlive( pFrame ) && ! pFrame->GetWindow()->IsInModalMode() )
+ {
+ SalMenuEvent aMenuEvt;
+ aMenuEvt.mnId = mpMenuItem->mnId;
+ aMenuEvt.mpMenu = mpMenuItem->mpVCLMenu;
+ pFrame->CallCallback(SALEVENT_MENUCOMMAND, &aMenuEvt);
+ }
+}
+@end
+