summaryrefslogtreecommitdiff
path: root/vcl/source
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source')
-rw-r--r--vcl/source/app/svdata.cxx2
-rw-r--r--vcl/source/control/button.cxx5
-rw-r--r--vcl/source/control/ctrl.cxx29
-rw-r--r--vcl/source/outdev/text.cxx9
-rw-r--r--vcl/source/window/dialog.cxx30
-rw-r--r--vcl/source/window/menu.cxx41
-rw-r--r--vcl/source/window/menubarwindow.cxx36
-rw-r--r--vcl/source/window/menubarwindow.hxx6
-rw-r--r--vcl/source/window/menufloatingwindow.cxx10
-rw-r--r--vcl/source/window/syswin.cxx13
-rw-r--r--vcl/source/window/window.cxx11
-rw-r--r--vcl/source/window/winproc.cxx21
12 files changed, 183 insertions, 30 deletions
diff --git a/vcl/source/app/svdata.cxx b/vcl/source/app/svdata.cxx
index 8b1a2a60e380..9c2cde1c31b1 100644
--- a/vcl/source/app/svdata.cxx
+++ b/vcl/source/app/svdata.cxx
@@ -84,6 +84,8 @@ ImplSVData::ImplSVData()
memset( this, 0, sizeof( ImplSVData ) );
maHelpData.mbAutoHelpId = true;
maNWFData.maMenuBarHighlightTextColor = Color( COL_TRANSPARENT );
+ maNWFData.mbEnableAccel = 1;
+ maNWFData.mbAutoAccel = 0;
}
ImplSVGDIData::~ImplSVGDIData()
diff --git a/vcl/source/control/button.cxx b/vcl/source/control/button.cxx
index 0c330d6d88ea..ca27059e68b1 100644
--- a/vcl/source/control/button.cxx
+++ b/vcl/source/control/button.cxx
@@ -504,8 +504,9 @@ void Button::ImplDrawAlignedImage(OutputDevice* pDev, Point& rPos,
if (bDrawText)
{
- ImplSetFocusRect(Rectangle(aTextPos, aTextSize));
- pDev->DrawText(Rectangle(aTextPos, aTextSize), aText, nTextStyle, pVector, pDisplayText);
+ Rectangle aTOutRect( aTextPos, aTextSize );
+ ImplSetFocusRect( aTOutRect );
+ DrawControlText( *pDev, aTOutRect, aText, nTextStyle, pVector, pDisplayText );
}
else
{
diff --git a/vcl/source/control/ctrl.cxx b/vcl/source/control/ctrl.cxx
index 21056db4c58f..59d3389bc47a 100644
--- a/vcl/source/control/ctrl.cxx
+++ b/vcl/source/control/ctrl.cxx
@@ -38,6 +38,7 @@ void Control::ImplInitControlData()
mbHasControlFocus = false;
mbFont = false;
mbForeground = false;
+ mbShowAccelerator = false;
mpControlData = new ImplControlData;
}
@@ -379,6 +380,16 @@ void Control::ImplDrawFrame( OutputDevice* pDev, Rectangle& rRect )
pDev->OutputDevice::SetSettings( aOriginalSettings );
}
+void Control::SetShowAccelerator(bool bVal)
+{
+ mbShowAccelerator = bVal;
+};
+
+bool Control::GetShowAccelerator() const
+{
+ return mbShowAccelerator;
+}
+
ControlLayoutData::~ControlLayoutData()
{
if( m_pParent )
@@ -442,15 +453,27 @@ void Control::ImplInitSettings(const bool _bFont, const bool _bForeground)
void Control::DrawControlText( OutputDevice& _rTargetDevice, Rectangle& _io_rRect, const OUString& _rStr,
DrawTextFlags _nStyle, MetricVector* _pVector, OUString* _pDisplayText ) const
{
+ OUString rPStr = _rStr;
+ DrawTextFlags nPStyle = _nStyle;
+
+ bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+ bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel;
+
+ if (!accel || (autoacc && !mbShowAccelerator))
+ {
+ rPStr = GetNonMnemonicString( _rStr );
+ nPStyle &= ~DrawTextFlags::HideMnemonic;
+ }
+
if ( !mpControlData->mpReferenceDevice || ( mpControlData->mpReferenceDevice == &_rTargetDevice ) )
{
- _io_rRect = _rTargetDevice.GetTextRect( _io_rRect, _rStr, _nStyle );
- _rTargetDevice.DrawText( _io_rRect, _rStr, _nStyle, _pVector, _pDisplayText );
+ _io_rRect = _rTargetDevice.GetTextRect( _io_rRect, rPStr, nPStyle );
+ _rTargetDevice.DrawText( _io_rRect, rPStr, nPStyle, _pVector, _pDisplayText );
}
else
{
ControlTextRenderer aRenderer( *this, _rTargetDevice, *mpControlData->mpReferenceDevice );
- _io_rRect = aRenderer.DrawText( _io_rRect, _rStr, _nStyle, _pVector, _pDisplayText );
+ _io_rRect = aRenderer.DrawText( _io_rRect, rPStr, nPStyle, _pVector, _pDisplayText );
}
}
diff --git a/vcl/source/outdev/text.cxx b/vcl/source/outdev/text.cxx
index 69e957ecb6eb..51ca684bba20 100644
--- a/vcl/source/outdev/text.cxx
+++ b/vcl/source/outdev/text.cxx
@@ -2230,6 +2230,9 @@ void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr,
}
}
+ bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+ bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel;
+
if ( nStyle & DrawTextFlags::Disable && ! pVector )
{
Color aOldTextColor;
@@ -2266,7 +2269,8 @@ void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr,
SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() );
DrawText( rPos, aStr, nIndex, nLen, pVector, pDisplayText );
- if ( !(GetSettings().GetStyleSettings().GetOptions() & StyleSettingsOptions::NoMnemonics) && !pVector )
+ if ( !(GetSettings().GetStyleSettings().GetOptions() & StyleSettingsOptions::NoMnemonics) && !pVector
+ && accel && (!autoacc || !(nStyle & DrawTextFlags::HideMnemonic)) )
{
if ( nMnemonicPos != -1 )
ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, nMnemonicWidth );
@@ -2278,7 +2282,8 @@ void OutputDevice::DrawCtrlText( const Point& rPos, const OUString& rStr,
else
{
DrawText( rPos, aStr, nIndex, nLen, pVector, pDisplayText );
- if ( !(GetSettings().GetStyleSettings().GetOptions() & StyleSettingsOptions::NoMnemonics) && !pVector )
+ if ( !(GetSettings().GetStyleSettings().GetOptions() & StyleSettingsOptions::NoMnemonics) && !pVector
+ && accel && (!autoacc || !(nStyle & DrawTextFlags::HideMnemonic)) )
{
if ( nMnemonicPos != -1 )
ImplDrawMnemonicLine( nMnemonicX, nMnemonicY, nMnemonicWidth );
diff --git a/vcl/source/window/dialog.cxx b/vcl/source/window/dialog.cxx
index b6679d10189b..5f3acda65a3c 100644
--- a/vcl/source/window/dialog.cxx
+++ b/vcl/source/window/dialog.cxx
@@ -585,6 +585,31 @@ IMPL_LINK_NOARG(Dialog, ImplAsyncCloseHdl)
return 0;
}
+bool Dialog::ImplHandleCmdEvent( const CommandEvent& rCEvent )
+{
+ if (rCEvent.GetCommand() == CommandEventId::ModKeyChange)
+ {
+ const CommandModKeyData *pCData = rCEvent.GetModKeyData ();
+
+ Window *pGetChild = firstLogicalChildOfParent(this);
+ while (pGetChild)
+ {
+ Control *pControl = dynamic_cast<Control*>(pGetChild->ImplGetWindow());
+ if (pControl && pControl->GetText().indexOf('~') != -1)
+ {
+ if (pCData && pCData->IsMod2())
+ pControl->SetShowAccelerator(true);
+ else
+ pControl->SetShowAccelerator(false);
+ pControl->Invalidate(InvalidateFlags::Update);
+ }
+ pGetChild = nextLogicalChildOfParent(this, pGetChild);
+ }
+ return true;
+ }
+ return false;
+}
+
bool Dialog::Notify( NotifyEvent& rNEvt )
{
// first call the base class due to Tab control
@@ -628,6 +653,11 @@ bool Dialog::Notify( NotifyEvent& rNEvt )
}
}
+ else if (rNEvt.GetType() == MouseNotifyEvent::COMMAND)
+ {
+ if (ImplHandleCmdEvent( *rNEvt.GetCommandEvent()))
+ return true;
+ }
}
return nRet;
diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx
index cb836371d077..543f259f6cd9 100644
--- a/vcl/source/window/menu.cxx
+++ b/vcl/source/window/menu.cxx
@@ -2022,6 +2022,12 @@ void Menu::ImplPaint(vcl::RenderContext& rRenderContext,
aTmpPos.Y() += nTextOffsetY;
DrawTextFlags nStyle = nTextStyle | DrawTextFlags::Mnemonic;
+ const Menu *pMenu = this;
+ while (!pMenu->IsMenuBar() && pMenu->pStartedFrom)
+ pMenu = pMenu->pStartedFrom;
+ if (pMenu->IsMenuBar() && (static_cast<MenuBarWindow*>(pMenu->pWindow.get()))->GetMBWHideAccel())
+ nStyle |= DrawTextFlags::HideMnemonic;
+
if (pData->bIsTemporary)
nStyle |= DrawTextFlags::Disable;
MetricVector* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
@@ -2602,6 +2608,37 @@ bool MenuBar::ImplHandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
return bDone;
}
+bool MenuBar::ImplHandleCmdEvent( const CommandEvent& rCEvent )
+{
+ bool bDone = false;
+ const CommandModKeyData* pCData;
+
+ // No keyboard processing when system handles the menu or our menubar is invisible
+ if( !IsDisplayable() ||
+ ( ImplGetSalMenu() && ImplGetSalMenu()->VisibleMenuBar() ) )
+ return bDone;
+
+ // check for enabled, if this method is called from another window...
+ MenuBarWindow* pWin = static_cast<MenuBarWindow*>(ImplGetWindow());
+ if ( pWin && pWin->IsEnabled() && pWin->IsInputEnabled() && ! pWin->IsInModalMode() )
+ {
+ if (rCEvent.GetCommand() == CommandEventId::ModKeyChange)
+ {
+ pCData = rCEvent.GetModKeyData ();
+ if (pWin->nHighlightedItem == ITEMPOS_INVALID)
+ {
+ if (pCData && pCData->IsMod2())
+ pWin->SetMBWHideAccel(false);
+ else
+ pWin->SetMBWHideAccel(true);
+ pWin->Invalidate(InvalidateFlags::Update);
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
void MenuBar::SelectItem(sal_uInt16 nId)
{
if (pWindow)
@@ -2886,6 +2923,10 @@ sal_uInt16 PopupMenu::ImplExecute( vcl::Window* pW, const Rectangle& rRect, Floa
if ( !pSFrom && ( PopupMenu::IsInExecute() || !GetItemCount() ) )
return 0;
+ // set the flag to hide or show accelerators in the menu depending on whether the menu was launched by mouse or keyboard shortcut
+ if( pSFrom && pSFrom->IsMenuBar())
+ ((static_cast<MenuBarWindow*>(pSFrom->pWindow.get())))->SetMBWHideAccel(!(static_cast<MenuBarWindow*>(pSFrom->pWindow.get())->GetMBWMenuKey()));
+
delete mpLayoutData, mpLayoutData = NULL;
ImplSVData* pSVData = ImplGetSVData();
diff --git a/vcl/source/window/menubarwindow.cxx b/vcl/source/window/menubarwindow.cxx
index e6fe6461c023..602366f70d63 100644
--- a/vcl/source/window/menubarwindow.cxx
+++ b/vcl/source/window/menubarwindow.cxx
@@ -133,6 +133,7 @@ MenuBarWindow::MenuBarWindow( vcl::Window* pParent ) :
nSaveFocusId = 0;
bIgnoreFirstMove = true;
bStayActive = false;
+ SetMBWHideAccel(true);
ResMgr* pResMgr = ImplGetResMgr();
@@ -383,6 +384,7 @@ void MenuBarWindow::PopupClosed( Menu* pPopup )
void MenuBarWindow::MouseButtonDown( const MouseEvent& rMEvt )
{
mbAutoPopup = true;
+ SetMBWMenuKey(false);
sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() );
if ( ( nEntry != ITEMPOS_INVALID ) && !pActivePopup )
{
@@ -407,7 +409,18 @@ void MenuBarWindow::MouseMove( const MouseEvent& rMEvt )
if ( rMEvt.IsLeaveWindow() )
{
if ( nRolloveredItem != ITEMPOS_INVALID && nRolloveredItem != nHighlightedItem )
- Invalidate(); //HighlightItem( nRolloveredItem, false );
+ {
+ // there is a spurious MouseMove generated after a menu is launched from the keyboard, hence this...
+ if (nHighlightedItem != ITEMPOS_INVALID)
+ {
+ bool hide = GetMBWHideAccel();
+ SetMBWHideAccel(true);
+ Invalidate(); //HighlightItem( nRolloveredItem, false );
+ SetMBWHideAccel(hide);
+ }
+ else
+ Invalidate(); //HighlightItem( nRolloveredItem, false );
+ }
nRolloveredItem = ITEMPOS_INVALID;
return;
@@ -444,6 +457,9 @@ void MenuBarWindow::ChangeHighlightItem( sal_uInt16 n, bool bSelectEntry, bool b
if( ! pMenu )
return;
+ // always hide accelerators when updating the menu bar...
+ SetMBWHideAccel(true);
+
// #57934# close active popup if applicable, as TH's background storage works.
MenuItemData* pNextData = pMenu->pItemList->GetDataFromPos( n );
if ( pActivePopup && pActivePopup->ImplGetWindow() && ( !pNextData || ( pActivePopup != pNextData->pSubMenu ) ) )
@@ -824,18 +840,12 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
{
if( pActivePopup )
{
- // bring focus to menu bar without any open popup
+ // hide the menu and remove the focus...
mbAutoPopup = false;
- sal_uInt16 n = nHighlightedItem;
- nHighlightedItem = ITEMPOS_INVALID;
- bStayActive = true;
- ChangeHighlightItem( n, false );
- bStayActive = false;
KillActivePopup();
- GrabFocus();
}
- else
- ChangeHighlightItem( ITEMPOS_INVALID, false );
+
+ ChangeHighlightItem( ITEMPOS_INVALID, false );
if( nCode == KEY_F6 && rKEvent.GetKeyCode().IsMod1() )
{
@@ -847,7 +857,8 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
}
}
- if ( !bDone && ( bFromMenu || rKEvent.GetKeyCode().IsMod2() ) )
+ bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+ if ( !bDone && ( bFromMenu || (rKEvent.GetKeyCode().IsMod2() && accel) ) )
{
sal_Unicode nCharCode = rKEvent.GetCharCode();
if ( nCharCode )
@@ -857,6 +868,9 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu )
if ( pData && (nEntry != ITEMPOS_INVALID) )
{
mbAutoPopup = true;
+ SetMBWMenuKey(true);
+ SetMBWHideAccel(true);
+ Invalidate(InvalidateFlags::Update);
ChangeHighlightItem( nEntry, true );
bDone = true;
}
diff --git a/vcl/source/window/menubarwindow.hxx b/vcl/source/window/menubarwindow.hxx
index 23d87415a37f..579e03b687f1 100644
--- a/vcl/source/window/menubarwindow.hxx
+++ b/vcl/source/window/menubarwindow.hxx
@@ -80,6 +80,8 @@ private:
bool mbAutoPopup;
bool bIgnoreFirstMove;
bool bStayActive;
+ bool mbHideAccel;
+ bool mbMenuKey;
VclPtr<DecoToolBox> aCloseBtn;
VclPtr<PushButton> aFloatBtn;
@@ -145,6 +147,10 @@ public:
virtual Rectangle GetMenuBarButtonRectPixel(sal_uInt16 nId) SAL_OVERRIDE;
virtual void RemoveMenuBarButton(sal_uInt16 nId) SAL_OVERRIDE;
virtual bool HandleMenuButtonEvent(sal_uInt16 i_nButtonId) SAL_OVERRIDE;
+ virtual void SetMBWHideAccel (bool val) { mbHideAccel = val; }
+ virtual bool GetMBWHideAccel (void) const { return mbHideAccel; }
+ virtual void SetMBWMenuKey (bool val) { mbMenuKey = val; }
+ virtual bool GetMBWMenuKey (void) const { return mbMenuKey; }
};
#endif // INCLUDED_VCL_SOURCE_WINDOW_MENUBARWINDOW_HXX
diff --git a/vcl/source/window/menufloatingwindow.cxx b/vcl/source/window/menufloatingwindow.cxx
index 065b9dcec388..4dbd276a8303 100644
--- a/vcl/source/window/menufloatingwindow.cxx
+++ b/vcl/source/window/menufloatingwindow.cxx
@@ -19,6 +19,7 @@
#include "menufloatingwindow.hxx"
#include "menuitemlist.hxx"
+#include "menubarwindow.hxx"
#include <svdata.hxx>
#include <vcl/decoview.hxx>
@@ -1108,8 +1109,13 @@ void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent )
sal_Unicode nCharCode = rKEvent.GetCharCode();
sal_uInt16 nPos = 0;
sal_uInt16 nDuplicates = 0;
- MenuItemData* pData = (nCharCode && pMenu) ? pMenu->GetItemList()->SearchItem( nCharCode, rKEvent.GetKeyCode(), nPos, nDuplicates, nHighlightedItem ) : NULL;
- if ( pData )
+ MenuItemData* pData = (nCharCode && pMenu) ?
+ pMenu->GetItemList()->SearchItem(nCharCode, rKEvent.GetKeyCode(), nPos, nDuplicates, nHighlightedItem) : NULL;
+ bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+ Menu *men = pMenu;
+ while (!men->IsMenuBar())
+ men = men->pStartedFrom;
+ if ( pData && (static_cast<MenuBarWindow*>(men->pWindow.get()))->GetMBWMenuKey () && accel )
{
if ( pData->pSubMenu || nDuplicates > 1 )
{
diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx
index c08a60168a93..2ec48b30bc85 100644
--- a/vcl/source/window/syswin.cxx
+++ b/vcl/source/window/syswin.cxx
@@ -126,7 +126,8 @@ void SystemWindow::dispose()
bool SystemWindow::Notify( NotifyEvent& rNEvt )
{
// capture KeyEvents for menu handling
- if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT )
+ if (rNEvt.GetType() == MouseNotifyEvent::KEYINPUT ||
+ rNEvt.GetType() == MouseNotifyEvent::COMMAND)
{
MenuBar* pMBar = mpMenuBar;
if ( !pMBar && ( GetType() == WINDOW_FLOATINGWINDOW ) )
@@ -135,7 +136,15 @@ bool SystemWindow::Notify( NotifyEvent& rNEvt )
if( pWin && pWin->IsSystemWindow() )
pMBar = static_cast<SystemWindow*>(pWin)->GetMenuBar();
}
- if ( pMBar && pMBar->ImplHandleKeyEvent( *rNEvt.GetKeyEvent(), false ) )
+ bool bDone(false);
+ if (pMBar)
+ {
+ if (rNEvt.GetType() == MouseNotifyEvent::COMMAND)
+ bDone = pMBar->ImplHandleCmdEvent(*rNEvt.GetCommandEvent());
+ else
+ bDone = pMBar->ImplHandleKeyEvent(*rNEvt.GetKeyEvent(), false);
+ }
+ if (bDone)
return true;
}
diff --git a/vcl/source/window/window.cxx b/vcl/source/window/window.cxx
index 199888a1141a..fc35c6f48457 100644
--- a/vcl/source/window/window.cxx
+++ b/vcl/source/window/window.cxx
@@ -1919,6 +1919,17 @@ void Window::SimulateKeyPress( sal_uInt16 nKeyCode ) const
void Window::KeyInput( const KeyEvent& rKEvt )
{
+ KeyCode cod = rKEvt.GetKeyCode ();
+ bool accel = ImplGetSVData()->maNWFData.mbEnableAccel;
+ bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel;
+
+ // do not respond to accelerators unless Alt is held */
+ if (cod.GetCode () >= 0x200 && cod.GetCode () <= 0x219)
+ {
+ if (!accel) return;
+ if (autoacc && cod.GetModifier () != 0x4000) return;
+ }
+
NotifyEvent aNEvt( MouseNotifyEvent::KEYINPUT, this, &rKEvt );
if ( !CompatNotify( aNEvt ) )
mpWindowImpl->mbKeyInput = true;
diff --git a/vcl/source/window/winproc.cxx b/vcl/source/window/winproc.cxx
index c1b31962b6a5..280db2325733 100644
--- a/vcl/source/window/winproc.cxx
+++ b/vcl/source/window/winproc.cxx
@@ -2165,17 +2165,22 @@ static void ImplHandleSalKeyMod( vcl::Window* pWindow, SalKeyModEvent* pEvent )
// #105224# send commandevent to allow special treatment of Ctrl-LeftShift/Ctrl-RightShift etc.
- // find window
- vcl::Window* pChild = ImplGetKeyInputWindow( pWindow );
- if ( !pChild )
- return;
+ // find window - first look to see if the system window is available
+ vcl::Window* pChild = pWindow->ImplGetWindowImpl()->mpFirstChild;
- // send modkey events only if useful data is available
- if( pEvent->mnModKeyCode != 0 )
+ while ( pChild )
{
- CommandModKeyData data( pEvent->mnModKeyCode );
- ImplCallCommand( pChild, CommandEventId::ModKeyChange, &data );
+ if ( pChild->ImplGetWindowImpl()->mbSysWin )
+ break;
+ pChild = pChild->ImplGetWindowImpl()->mpNext;
}
+ //...if not, try to find a key input window...
+ if (!pChild) ImplGetKeyInputWindow( pWindow );
+ //...otherwise fail safe...
+ if (!pChild) pChild = pWindow;
+
+ CommandModKeyData data( pEvent->mnModKeyCode );
+ ImplCallCommand( pChild, CommandEventId::ModKeyChange, &data );
}
static void ImplHandleInputLanguageChange( vcl::Window* pWindow )