tdf#74377 Keyboard shortcuts for context menus

Configurable through the options dialog. The default behavior
depends on the current vclplug (hide for gtk2/3 and OS X, show
otherwise).

Menus currently affected by this change:

- SfxDispatcher based context menus
- chart2 context menus
- vcl's Edit control context menu
- Several MenuBarManager based toolbar dropdowns.

Change-Id: Iad9fb99dc90e01c17cba9c07c1a2b262b920e11d
Reviewed-on: https://gerrit.libreoffice.org/28849
Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
Tested-by: Maxim Monastirsky <momonasmon@gmail.com>
This commit is contained in:
Maxim Monastirsky 2016-09-14 02:02:38 +03:00
parent ebe46f14a2
commit 74fd959945
14 changed files with 182 additions and 21 deletions

View File

@ -630,6 +630,7 @@ OfaViewTabPage::OfaViewTabPage(vcl::Window* pParent, const SfxItemSet& rSet)
get(m_pAAPointLimitLabel, "aafrom");
get(m_pAAPointLimit, "aanf");
get(m_pMenuIconsLB, "menuicons");
get(m_pContextMenuShortcutsLB, "contextmenushortcuts");
get(m_pFontShowCB, "showfontpreview");
get(m_pUseHardwareAccell, "useaccel");
get(m_pUseAntiAliase, "useaa");
@ -711,6 +712,7 @@ void OfaViewTabPage::dispose()
m_pAAPointLimitLabel.clear();
m_pAAPointLimit.clear();
m_pMenuIconsLB.clear();
m_pContextMenuShortcutsLB.clear();
m_pFontShowCB.clear();
m_pUseHardwareAccell.clear();
m_pUseAntiAliase.clear();
@ -867,6 +869,16 @@ bool OfaViewTabPage::FillItemSet( SfxItemSet* )
bAppearanceChanged = true;
}
if(m_pContextMenuShortcutsLB->IsValueChangedFromSaved())
{
aMenuOpt.SetContextMenuShortcuts(m_pContextMenuShortcutsLB->GetSelectEntryPos() == 0 ?
TRISTATE_INDET :
static_cast<TriState>(m_pContextMenuShortcutsLB->GetSelectEntryPos() - 1));
bModified = true;
bMenuOptModified = true;
bAppearanceChanged = true;
}
// #i95644# if disabled, do not use value, see in ::Reset()
if(m_pUseHardwareAccell->IsEnabled())
{
@ -994,6 +1006,11 @@ void OfaViewTabPage::Reset( const SfxItemSet* )
m_pMenuIconsLB->SelectEntryPos(aMenuOpt.GetMenuIconsState() == 2 ? 0 : aMenuOpt.GetMenuIconsState() + 1);
m_pMenuIconsLB->SaveValue();
TriState eContextMenuShortcuts = aMenuOpt.GetContextMenuShortcuts();
bool bContextMenuShortcutsNonDefault = eContextMenuShortcuts == TRISTATE_FALSE || eContextMenuShortcuts == TRISTATE_TRUE;
m_pContextMenuShortcutsLB->SelectEntryPos(bContextMenuShortcutsNonDefault ? eContextMenuShortcuts + 1 : 0);
m_pContextMenuShortcutsLB->SaveValue();
{ // #i95644# HW accel (unified to disable mechanism)
if(pCanvasSettings->IsHardwareAccelerationAvailable())
{

View File

@ -89,6 +89,7 @@ private:
VclPtr<MetricField> m_pAAPointLimit;
VclPtr<ListBox> m_pMenuIconsLB;
VclPtr<ListBox> m_pContextMenuShortcutsLB;
VclPtr<CheckBox> m_pFontShowCB;

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<!-- Generated with glade 3.20.0 -->
<interface>
<requires lib="gtk+" version="3.0"/>
<object class="GtkAdjustment" id="adjustment1">
@ -195,6 +195,40 @@
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkComboBoxText" id="contextmenushortcuts">
<property name="visible">True</property>
<property name="can_focus">False</property>
<items>
<item translatable="yes">Automatic</item>
<item translatable="yes">Hide</item>
<item translatable="yes">Show</item>
</items>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label10">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">6</property>
<property name="margin_bottom">6</property>
<property name="label" translatable="yes">Shortcuts in context menus:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">contextmenushortcuts</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>

View File

@ -1902,6 +1902,7 @@ void Desktop::OverrideSystemSettings( AllSettings& rSettings )
SvtMenuOptions aMenuOpt;
hStyleSettings.SetUseImagesInMenus(aMenuOpt.GetMenuIconsState());
hStyleSettings.SetContextMenuShortcuts(aMenuOpt.GetContextMenuShortcuts());
hStyleSettings.SetDragFullOptions( nDragFullOptions );
rSettings.SetStyleSettings ( hStyleSettings );
}

View File

@ -746,6 +746,7 @@ IMPL_LINK_TYPED( MenuBarManager, Activate, Menu *, pMenu, bool )
bool bDontHide = SvtMenuOptions().IsEntryHidingEnabled();
const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings();
bool bShowMenuImages = rSettings.GetUseImagesInMenus();
bool bShowShortcuts = m_bHasMenuBar || rSettings.GetContextMenuShortcuts();
bool bHasDisabledEntries = SvtCommandOptions().HasEntries( SvtCommandOptions::CMDOPTION_DISABLED );
SolarMutexGuard g;
@ -794,18 +795,23 @@ IMPL_LINK_TYPED( MenuBarManager, Activate, Menu *, pMenu, bool )
}
// Try to set accelerator keys
if ( m_bHasMenuBar )
{
RetrieveShortcuts( m_aMenuItemHandlerVector );
if ( bShowShortcuts )
RetrieveShortcuts( m_aMenuItemHandlerVector );
std::vector< MenuItemHandler* >::iterator p;
for ( p = m_aMenuItemHandlerVector.begin(); p != m_aMenuItemHandlerVector.end(); ++p )
{
MenuItemHandler* pMenuItemHandler = *p;
// Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex
// Only non-popup menu items can have a short-cut
if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex )
if ( !bShowShortcuts )
{
pMenu->SetAccelKey( pMenuItemHandler->nItemId, vcl::KeyCode() );
}
else if ( pMenuItemHandler->aMenuItemURL == aCmdHelpIndex )
{
// Set key code, workaround for hard-coded shortcut F1 mapped to .uno:HelpIndex
// Only non-popup menu items can have a short-cut
vcl::KeyCode aKeyCode( KEY_F1 );
pMenu->SetAccelKey( pMenuItemHandler->nItemId, aKeyCode );
}

View File

@ -66,6 +66,8 @@ class SAL_WARN_UNUSED SVT_DLLPUBLIC SvtMenuOptions: public utl::detail::Options
bool IsEntryHidingEnabled() const;
TriState GetMenuIconsState() const;
void SetMenuIconsState(TriState eState);
TriState GetContextMenuShortcuts() const;
void SetContextMenuShortcuts(TriState eState);
private:

View File

@ -425,8 +425,11 @@ public:
void SetHideDisabledMenuItems( bool bHideDisabledMenuItems );
bool GetHideDisabledMenuItems() const;
void SetAcceleratorsInContextMenus( bool bAcceleratorsInContextMenus );
bool GetAcceleratorsInContextMenus() const;
void SetContextMenuShortcuts( TriState eContextMenuShortcuts );
bool GetContextMenuShortcuts() const;
void SetPreferredContextMenuShortcuts( bool bContextMenuShortcuts );
bool GetPreferredContextMenuShortcuts() const;
void SetPrimaryButtonWarpsSlider( bool bPrimaryButtonWarpsSlider );
bool GetPrimaryButtonWarpsSlider() const;

View File

@ -2799,6 +2799,32 @@
</info>
<value>true</value>
</prop>
<prop oor:name="ShortcutsInContextMenus" oor:type="xs:short" oor:nillable="false">
<!-- UIHints: Tools Options - General View [Section] Options -->
<info>
<desc>Indicates whether keyboard shortcuts should be displayed in
context menus.</desc>
<label>Shortcuts in context menus</label>
</info>
<constraints>
<enumeration oor:value="0">
<info>
<desc>Hide</desc>
</info>
</enumeration>
<enumeration oor:value="1">
<info>
<desc>Show</desc>
</info>
</enumeration>
<enumeration oor:value="2">
<info>
<desc>Use the default setting for the current platform.</desc>
</info>
</enumeration>
</constraints>
<value>2</value>
</prop>
</group>
<group oor:name="Window">
<info>

View File

@ -40,16 +40,19 @@ using namespace ::com::sun::star::uno ;
#define DEFAULT_DONTHIDEDISABLEDENTRIES false
#define DEFAULT_FOLLOWMOUSE true
#define DEFAULT_MENUICONS TRISTATE_INDET
#define DEFAULT_CONTEXTMENUSHORTCUTS TRISTATE_INDET
#define PROPERTYNAME_DONTHIDEDISABLEDENTRIES "DontHideDisabledEntry"
#define PROPERTYNAME_FOLLOWMOUSE "FollowMouse"
#define PROPERTYNAME_SHOWICONSINMENUES "ShowIconsInMenues"
#define PROPERTYNAME_SYSTEMICONSINMENUES "IsSystemIconsInMenus"
#define PROPERTYNAME_SHORTCUTSINCONTEXMENU "ShortcutsInContextMenus"
#define PROPERTYHANDLE_DONTHIDEDISABLEDENTRIES 0
#define PROPERTYHANDLE_FOLLOWMOUSE 1
#define PROPERTYHANDLE_SHOWICONSINMENUES 2
#define PROPERTYHANDLE_SYSTEMICONSINMENUES 3
#define PROPERTYHANDLE_SHORTCUTSINCONTEXMENU 4
#include <tools/link.hxx>
@ -64,6 +67,7 @@ class SvtMenuOptions_Impl : public ConfigItem
bool m_bDontHideDisabledEntries ; /// cache "DontHideDisabledEntries" of Menu section
bool m_bFollowMouse ; /// cache "FollowMouse" of Menu section
TriState m_eMenuIcons ; /// cache "MenuIcons" of Menu section
TriState m_eContextMenuShortcuts ; /// cache "ShortcutsInContextMenus" of Menu section
// public methods
@ -110,6 +114,16 @@ class SvtMenuOptions_Impl : public ConfigItem
// tdf#93451: don't Commit() here, it's too early
}
TriState GetContextMenuShortcuts() const
{ return m_eContextMenuShortcuts; }
void SetContextMenuShortcuts(TriState eState)
{
m_eContextMenuShortcuts = eState;
SetModified();
Commit();
}
// private methods
private:
@ -135,6 +149,7 @@ SvtMenuOptions_Impl::SvtMenuOptions_Impl()
, m_bDontHideDisabledEntries ( DEFAULT_DONTHIDEDISABLEDENTRIES )
, m_bFollowMouse ( DEFAULT_FOLLOWMOUSE )
, m_eMenuIcons ( DEFAULT_MENUICONS )
, m_eContextMenuShortcuts ( DEFAULT_CONTEXTMENUSHORTCUTS )
{
// Use our static list of configuration keys to get his values.
Sequence< OUString > seqNames = impl_GetPropertyNames();
@ -190,6 +205,13 @@ SvtMenuOptions_Impl::SvtMenuOptions_Impl()
seqValues[nProperty] >>= bSystemMenuIcons;
}
break;
case PROPERTYHANDLE_SHORTCUTSINCONTEXMENU : {
DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SHORT), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\ShortcutsInContextMenus\"?" );
sal_Int16 nContextMenuShortcuts;
if ( seqValues[nProperty] >>= nContextMenuShortcuts )
m_eContextMenuShortcuts = static_cast<TriState>(nContextMenuShortcuts);
}
break;
}
}
@ -250,6 +272,13 @@ void SvtMenuOptions_Impl::Notify( const Sequence< OUString >& seqPropertyNames )
DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_BOOLEAN), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\IsSystemIconsInMenus\"?" );
bMenuSettingsChanged |= seqValues[nProperty] >>= bSystemMenuIcons;
}
else if( seqPropertyNames[nProperty] == PROPERTYNAME_SHORTCUTSINCONTEXMENU )
{
DBG_ASSERT(!(seqValues[nProperty].getValueTypeClass()!=TypeClass_SHORT), "SvtMenuOptions_Impl::SvtMenuOptions_Impl()\nWho has changed the value type of \"Office.Common\\View\\Menu\\ShortcutsInContextMenus\"?" );
sal_Int16 nContextMenuShortcuts;
if ( seqValues[nProperty] >>= nContextMenuShortcuts )
m_eContextMenuShortcuts = static_cast<TriState>(nContextMenuShortcuts);
}
else assert( false && "SvtMenuOptions_Impl::Notify()\nUnknown property detected ... I can't handle these!\n" );
}
@ -289,6 +318,10 @@ void SvtMenuOptions_Impl::ImplCommit()
seqValues[nProperty] <<= bValue;
}
break;
case PROPERTYHANDLE_SHORTCUTSINCONTEXMENU : {
seqValues[nProperty] <<= static_cast<sal_Int16>(m_eContextMenuShortcuts);
}
break;
}
}
// Set properties in configuration.
@ -303,7 +336,8 @@ Sequence< OUString > const & SvtMenuOptions_Impl::impl_GetPropertyNames()
OUString(PROPERTYNAME_DONTHIDEDISABLEDENTRIES) ,
OUString(PROPERTYNAME_FOLLOWMOUSE) ,
OUString(PROPERTYNAME_SHOWICONSINMENUES) ,
OUString(PROPERTYNAME_SYSTEMICONSINMENUES)
OUString(PROPERTYNAME_SYSTEMICONSINMENUES) ,
OUString(PROPERTYNAME_SHORTCUTSINCONTEXMENU)
};
return seqPropertyNames;
}
@ -360,6 +394,18 @@ void SvtMenuOptions::SetMenuIconsState(TriState eState)
m_pImpl->SetMenuIconsState(eState);
}
TriState SvtMenuOptions::GetContextMenuShortcuts() const
{
MutexGuard aGuard( GetOwnStaticMutex() );
return m_pImpl->GetContextMenuShortcuts();
}
void SvtMenuOptions::SetContextMenuShortcuts(TriState eState)
{
MutexGuard aGuard( GetOwnStaticMutex() );
m_pImpl->SetContextMenuShortcuts(eState);
}
// private method
Mutex& SvtMenuOptions::GetOwnStaticMutex()

View File

@ -1217,7 +1217,7 @@ void AquaSalFrame::UpdateSettings( AllSettings& rSettings )
// images in menus false for MacOSX
aStyleSettings.SetPreferredUseImagesInMenus( false );
aStyleSettings.SetHideDisabledMenuItems( true );
aStyleSettings.SetAcceleratorsInContextMenus( false );
aStyleSettings.SetPreferredContextMenuShortcuts( false );
rSettings.SetStyleSettings( aStyleSettings );

View File

@ -186,7 +186,8 @@ struct ImplStyleData
rtl::OUString mIconTheme;
bool mbSkipDisabledInMenus;
bool mbHideDisabledMenuItems;
bool mbAcceleratorsInContextMenus;
bool mbPreferredContextMenuShortcuts;
TriState meContextMenuShortcuts;
//mbPrimaryButtonWarpsSlider == true for "jump to here" behavior for primary button, otherwise
//primary means scroll by single page. Secondary button takes the alternative behaviour
bool mbPrimaryButtonWarpsSlider;
@ -544,6 +545,7 @@ ImplStyleData::ImplStyleData() :
mbAutoMnemonic = true;
mnToolbarIconSize = ToolbarIconSize::Unknown;
meUseImagesInMenus = TRISTATE_INDET;
meContextMenuShortcuts = TRISTATE_INDET;
mnEdgeBlending = 35;
maEdgeBlendingTopLeftColor = RGB_COLORDATA(0xC0, 0xC0, 0xC0);
maEdgeBlendingBottomRightColor = RGB_COLORDATA(0x40, 0x40, 0x40);
@ -657,7 +659,8 @@ ImplStyleData::ImplStyleData( const ImplStyleData& rData ) :
mbPreferredUseImagesInMenus = rData.mbPreferredUseImagesInMenus;
mbSkipDisabledInMenus = rData.mbSkipDisabledInMenus;
mbHideDisabledMenuItems = rData.mbHideDisabledMenuItems;
mbAcceleratorsInContextMenus = rData.mbAcceleratorsInContextMenus;
mbPreferredContextMenuShortcuts = rData.mbPreferredContextMenuShortcuts;
meContextMenuShortcuts = rData.meContextMenuShortcuts;
mbPrimaryButtonWarpsSlider = rData.mbPrimaryButtonWarpsSlider;
mnToolbarIconSize = rData.mnToolbarIconSize;
mIconThemeScanner.reset(new vcl::IconThemeScanner(*rData.mIconThemeScanner));
@ -763,7 +766,7 @@ void ImplStyleData::SetStandardStyles()
mbPreferredUseImagesInMenus = true;
mbSkipDisabledInMenus = false;
mbHideDisabledMenuItems = false;
mbAcceleratorsInContextMenus = true;
mbPreferredContextMenuShortcuts = true;
mbPrimaryButtonWarpsSlider = false;
}
@ -1511,16 +1514,37 @@ StyleSettings::GetHideDisabledMenuItems() const
}
void
StyleSettings::SetAcceleratorsInContextMenus( bool bAcceleratorsInContextMenus )
StyleSettings::SetContextMenuShortcuts( TriState eContextMenuShortcuts )
{
CopyData();
mxData->mbAcceleratorsInContextMenus = bAcceleratorsInContextMenus;
mxData->meContextMenuShortcuts = eContextMenuShortcuts;
}
bool
StyleSettings::GetAcceleratorsInContextMenus() const
StyleSettings::GetContextMenuShortcuts() const
{
return mxData->mbAcceleratorsInContextMenus;
switch (mxData->meContextMenuShortcuts)
{
case TRISTATE_FALSE:
return false;
case TRISTATE_TRUE:
return true;
default: // TRISTATE_INDET:
return GetPreferredUseImagesInMenus();
}
}
void
StyleSettings::SetPreferredContextMenuShortcuts( bool bContextMenuShortcuts )
{
CopyData();
mxData->mbPreferredContextMenuShortcuts = bContextMenuShortcuts;
}
bool
StyleSettings::GetPreferredContextMenuShortcuts() const
{
return mxData->mbPreferredContextMenuShortcuts;
}
void
@ -2349,7 +2373,8 @@ bool StyleSettings::operator ==( const StyleSettings& rSet ) const
(mxData->mbPreferredUseImagesInMenus == rSet.mxData->mbPreferredUseImagesInMenus) &&
(mxData->mbSkipDisabledInMenus == rSet.mxData->mbSkipDisabledInMenus) &&
(mxData->mbHideDisabledMenuItems == rSet.mxData->mbHideDisabledMenuItems) &&
(mxData->mbAcceleratorsInContextMenus == rSet.mxData->mbAcceleratorsInContextMenus)&&
(mxData->mbPreferredContextMenuShortcuts == rSet.mxData->mbPreferredContextMenuShortcuts)&&
(mxData->meContextMenuShortcuts == rSet.mxData->meContextMenuShortcuts) &&
(mxData->mbPrimaryButtonWarpsSlider == rSet.mxData->mbPrimaryButtonWarpsSlider) &&
(mxData->maFontColor == rSet.mxData->maFontColor) &&
(mxData->mnEdgeBlending == rSet.mxData->mnEdgeBlending) &&

View File

@ -2815,7 +2815,7 @@ VclPtr<PopupMenu> Edit::CreatePopupMenu()
pPopup->SetMenuFlags( MenuFlags::HideDisabledEntries );
else
pPopup->SetMenuFlags ( MenuFlags::AlwaysShowDisabledEntries );
if ( rStyleSettings.GetAcceleratorsInContextMenus() )
if ( rStyleSettings.GetContextMenuShortcuts() )
{
pPopup->SetAccelKey( SV_MENU_EDIT_UNDO, vcl::KeyCode( KeyFuncType::UNDO ) );
pPopup->SetAccelKey( SV_MENU_EDIT_CUT, vcl::KeyCode( KeyFuncType::CUT ) );

View File

@ -4004,7 +4004,7 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
// menu disabled entries handling
aStyleSet.SetSkipDisabledInMenus( true );
aStyleSet.SetAcceleratorsInContextMenus( false );
aStyleSet.SetPreferredContextMenuShortcuts( false );
// menu colors
GtkStyle* pMenuStyle = gtk_widget_get_style( gWidgetData[m_nXScreen].gMenuWidget );
GtkStyle* pMenuItemStyle = gtk_rc_get_style( gWidgetData[m_nXScreen].gMenuItemMenuWidget );

View File

@ -1979,7 +1979,7 @@ void GtkSalGraphics::updateSettings( AllSettings& rSettings )
// menu disabled entries handling
aStyleSet.SetSkipDisabledInMenus( true );
aStyleSet.SetAcceleratorsInContextMenus( false );
aStyleSet.SetPreferredContextMenuShortcuts( false );
// menu colors
gtk_style_context_set_state(mpMenuStyle, GTK_STATE_FLAG_NORMAL);