You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdelibs/tdecore/kstdaccel.cpp

397 lines
17 KiB

/* This file is part of the KDE libraries
Copyright (C) 1997 Stefan Taferner (taferner@alpin.or.at)
Copyright (C) 2000 Nicolas Hadacek (haadcek@kde.org)
Copyright (C) 2001,2002 Ellis Whitehead (ellis@kde.org)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#define __KSTDACCEL_CPP_ 1
#include "kstdaccel.h"
#include "kaccelaction.h"
#include "kaccelbase.h"
#include <kconfig.h>
#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <kshortcut.h>
#include <kshortcutlist.h>
namespace KStdAccel
{
struct KStdAccelInfo
{
StdAccel id;
const char* psName;
const char* psDesc;
int cutDefault, cutDefault4, cutDefault3B, cutDefault4B;
KShortcut cut;
bool bInitialized;
};
/** Array of predefined KStdAccelInfo objects, which cover all
the "standard" accelerators. Each enum value from StdAccel
should appear in this table.
*/
static KStdAccelInfo g_infoStdAccel[] =
{
{AccelNone, "Group:File", I18N_NOOP("File"), 0, 0, 0, 0, KShortcut(), false },
{ Open, I18N_NOOP("Open"), 0, Qt::CTRL+Qt::Key_O, 0, 0, 0, KShortcut(), false },
{ New, I18N_NOOP("New"), 0, Qt::CTRL+Qt::Key_N, 0, 0, 0, KShortcut(), false },
{ Close, I18N_NOOP("Close"), 0, Qt::CTRL+Qt::Key_W, Qt::CTRL+Qt::Key_Escape, 0, Qt::CTRL+Qt::Key_W, KShortcut(), false },
{ Save, I18N_NOOP("Save"), 0, Qt::CTRL+Qt::Key_S, 0, 0, 0, KShortcut(), false },
{ Print, I18N_NOOP("Print"), 0, Qt::CTRL+Qt::Key_P, 0, 0, 0, KShortcut(), false },
{ Quit, I18N_NOOP("Quit"), 0, Qt::CTRL+Qt::Key_Q, 0, 0, 0, KShortcut(), false },
{AccelNone, "Group:Edit", I18N_NOOP("Edit"), 0, 0, 0, 0, KShortcut(), false },
{ Undo, I18N_NOOP("Undo"), 0, Qt::CTRL+Qt::Key_Z, 0, 0, 0, KShortcut(), false },
{ Redo, I18N_NOOP("Redo"), 0, Qt::CTRL+Qt::SHIFT+Qt::Key_Z, 0, 0, 0, KShortcut(), false },
{ Cut, I18N_NOOP("Cut"), 0, Qt::CTRL+Qt::Key_X, 0, Qt::SHIFT+Qt::Key_Delete, 0, KShortcut(), false },
{ Copy, I18N_NOOP("Copy"), 0, Qt::CTRL+Qt::Key_C, 0, Qt::CTRL+Qt::Key_Insert, 0, KShortcut(), false },
{ Paste, I18N_NOOP("Paste"), 0, Qt::CTRL+Qt::Key_V, 0, Qt::SHIFT+Qt::Key_Insert, 0, KShortcut(), false },
{ PasteSelection, I18N_NOOP("Paste Selection"), 0, 0, 0, Qt::CTRL+Qt::SHIFT+Qt::Key_Insert, 0, KShortcut(), false },
{ SelectAll, "SelectAll", I18N_NOOP("Select All"), Qt::CTRL+Qt::Key_A, 0, 0, 0, KShortcut(), false },
{ Deselect, I18N_NOOP("Deselect"), 0, Qt::CTRL+Qt::SHIFT+Qt::Key_A, 0, 0, 0, KShortcut(), false },
{ DeleteWordBack, "DeleteWordBack", I18N_NOOP("Delete Word Backwards"), Qt::CTRL+Qt::Key_Backspace, 0, 0, 0, KShortcut(), false },
{ DeleteWordForward, "DeleteWordForward", I18N_NOOP("Delete Word Forward"), Qt::CTRL+Qt::Key_Delete, 0, 0, 0, KShortcut(), false },
{ Find, I18N_NOOP("Find"), 0, Qt::CTRL+Qt::Key_F, 0, 0, 0, KShortcut(), false },
{ FindNext, "FindNext", I18N_NOOP("Find Next"), Qt::Key_F3, 0, 0, 0, KShortcut(), false },
{ FindPrev, "FindPrev", I18N_NOOP("Find Prev"), Qt::SHIFT+Qt::Key_F3, 0, 0, 0, KShortcut(), false },
{ Replace, I18N_NOOP("Replace"), 0, Qt::CTRL+Qt::Key_R, 0, 0, 0, KShortcut(), false },
{AccelNone, "Group:Navigation", I18N_NOOP("Navigation"), 0, 0, 0, 0, KShortcut(), false },
{ Home, I18N_NOOP2("Opposite to End","Home"), 0, Qt::CTRL+Qt::Key_Home, 0, Qt::Key_HomePage, 0, KShortcut(), false },
{ End, I18N_NOOP("End"), 0, Qt::CTRL+Qt::Key_End, 0, 0, 0, KShortcut(), false },
{ BeginningOfLine, "BeginningOfLine", I18N_NOOP("Beginning of Line"), Qt::Key_Home, 0, 0, 0, KShortcut(), false},
{ EndOfLine, "EndOfLine", I18N_NOOP("End of Line"), Qt::Key_End, 0, 0, 0, KShortcut(), false},
{ Prior, I18N_NOOP("Prior"), 0, TQt::Key_Prior, 0, 0, 0, KShortcut(), false },
{ Next, I18N_NOOP2("Opposite to Prior","Next"), 0, TQt::Key_Next, 0, 0, 0, KShortcut(), false },
{ GotoLine, "GotoLine", I18N_NOOP("Go to Line"), Qt::CTRL+Qt::Key_G, 0, 0, 0, KShortcut(), false },
{ AddBookmark, "AddBookmark", I18N_NOOP("Add Bookmark"), Qt::CTRL+Qt::Key_B, 0, 0, 0, KShortcut(), false },
{ ZoomIn, "ZoomIn", I18N_NOOP("Zoom In"), Qt::CTRL+Qt::Key_Plus, 0, 0, 0, KShortcut(), false },
{ ZoomOut, "ZoomOut", I18N_NOOP("Zoom Out"), Qt::CTRL+Qt::Key_Minus, 0, 0, 0, KShortcut(), false },
{ Up, I18N_NOOP("Up"), 0, Qt::ALT+Qt::Key_Up, 0, 0, 0, KShortcut(), false },
{ Back, I18N_NOOP("Back"), 0, Qt::ALT+Qt::Key_Left, 0, Qt::Key_Back, 0, KShortcut(), false },
{ Forward, I18N_NOOP("Forward"), 0, Qt::ALT+Qt::Key_Right, 0, Qt::Key_Forward, 0, KShortcut(), false },
{ Reload, I18N_NOOP("Reload"), 0, Qt::Key_F5, 0, Qt::Key_Refresh, 0, KShortcut(), false },
{ PopupMenuContext, "PopupMenuContext", I18N_NOOP("Popup Menu Context"), Qt::Key_Menu, 0, 0, 0, KShortcut(), false },
{ ShowMenubar, "ShowMenubar", I18N_NOOP("Show Menu Bar"), Qt::CTRL+Qt::Key_M, 0, 0, 0, KShortcut(), false },
{ BackwardWord, "BackwardWord", I18N_NOOP("Backward Word"), Qt::CTRL+Qt::Key_Left, 0, 0, 0, KShortcut(), false },
{ ForwardWord, "ForwardWord", I18N_NOOP("Forward Word"), Qt::CTRL+Qt::Key_Right, 0, 0, 0, KShortcut(), false },
{ TabNext, I18N_NOOP("Activate Next Tab"), 0, Qt::CTRL+Qt::Key_Period, 0, Qt::CTRL+Qt::Key_BracketRight, 0, KShortcut(), false },
{ TabPrev, I18N_NOOP("Activate Previous Tab"), 0, Qt::CTRL+Qt::Key_Comma, 0, Qt::CTRL+Qt::Key_BracketLeft, 0, KShortcut(), false },
{ FullScreen, "FullScreen", I18N_NOOP("Full Screen Mode"), Qt::CTRL+Qt::SHIFT+Qt::Key_F, 0, 0, 0, KShortcut(), false },
{AccelNone, "Group:Help", I18N_NOOP("Help"), 0, 0, 0, 0, KShortcut(), false },
{ Help, I18N_NOOP("Help"), 0, Qt::Key_F1, 0, 0, 0, KShortcut(), false },
{ WhatsThis, "WhatsThis", I18N_NOOP("What's This"), Qt::SHIFT+Qt::Key_F1, 0, 0, 0, KShortcut(), false },
{AccelNone, "Group:TextCompletion", I18N_NOOP("Text Completion"), 0, 0, 0, 0, KShortcut(), false },
{ TextCompletion, "TextCompletion", I18N_NOOP("Text Completion"), Qt::CTRL+Qt::Key_E, 0, 0, 0, KShortcut(), false },
{ PrevCompletion, "PrevCompletion", I18N_NOOP("Previous Completion Match"), Qt::CTRL+Qt::Key_Up, 0, 0, 0, KShortcut(), false },
{ NextCompletion, "NextCompletion", I18N_NOOP("Next Completion Match"), Qt::CTRL+Qt::Key_Down, 0, 0, 0, KShortcut(), false },
{ SubstringCompletion, "SubstringCompletion", I18N_NOOP("Substring Completion"), Qt::CTRL+Qt::Key_T, 0, 0, 0, KShortcut(), false },
{ RotateUp, "RotateUp", I18N_NOOP("Previous Item in List"), Qt::Key_Up, 0, 0, 0, KShortcut(), false },
{ RotateDown, "RotateDown", I18N_NOOP("Next Item in List"), Qt::Key_Down, 0, 0, 0, KShortcut(), false },
{ AccelNone, 0, 0, 0, 0, 0, 0, KShortcut(), false }
};
/** Search for the KStdAccelInfo object associated with the given @p id. */
static KStdAccelInfo* infoPtr( StdAccel id )
{
if( id != AccelNone ) {
// Linear search. Changing the data structure doesn't seem possible
// (since we need groups for the config stuff), but maybe a little
// additional hashtable wouldn't hurt.
for( uint i = 0; g_infoStdAccel[i].psName != 0; i++ ) {
if( g_infoStdAccel[i].id == id )
return &g_infoStdAccel[i];
}
}
return 0;
}
/** Initialize the accelerator @p id by checking if it is overridden
in the configuration file (and if it isn't, use the default).
*/
static void initialize( StdAccel id )
{
KConfigGroupSaver saver( KGlobal::config(), "Shortcuts" );
KStdAccelInfo* pInfo = infoPtr( id );
if( !pInfo ) {
kdWarning(125) << "KStdAccel: id not found!" << endl; // -- ellis
return;
}
if( saver.config()->hasKey( pInfo->psName ) ) {
TQString s = saver.config()->readEntry( pInfo->psName );
if( s != "none" )
pInfo->cut.init( s );
else
pInfo->cut.clear();
} else
pInfo->cut = shortcutDefault( id );
pInfo->bInitialized = true;
}
TQString name( StdAccel id )
{
KStdAccelInfo* pInfo = infoPtr( id );
if( !pInfo )
return TQString::null;
return pInfo->psName;
}
TQString label( StdAccel id )
{
KStdAccelInfo* pInfo = infoPtr( id );
if( !pInfo )
return TQString::null;
return i18n((pInfo->psDesc) ? pInfo->psDesc : pInfo->psName);
}
// TODO: Add psWhatsThis entry to KStdAccelInfo
TQString whatsThis( StdAccel /*id*/ )
{
// KStdAccelInfo* pInfo = infoPtr( id );
// if( pInfo && pInfo->psWhatsThis )
// return i18n(pInfo->psWhatsThis);
// else
return TQString::null;
}
const KShortcut& shortcut( StdAccel id )
{
KStdAccelInfo* pInfo = infoPtr( id );
if( !pInfo )
return KShortcut::null();
if( !pInfo->bInitialized )
initialize( id );
return pInfo->cut;
}
StdAccel findStdAccel( const KKeySequence& seq )
{
if( !seq.isNull() ) {
for( uint i = 0; g_infoStdAccel[i].psName != 0; i++ ) {
StdAccel id = g_infoStdAccel[i].id;
if( id != AccelNone ) {
if( !g_infoStdAccel[i].bInitialized )
initialize( id );
if( g_infoStdAccel[i].cut.contains( seq ) )
return id;
}
}
}
return AccelNone;
}
KShortcut shortcutDefault( StdAccel id )
{
return (KAccelAction::useFourModifierKeys())
? shortcutDefault4(id) : shortcutDefault3(id);
}
KShortcut shortcutDefault3( StdAccel id )
{
KShortcut cut;
KStdAccelInfo* pInfo = infoPtr( id );
if( pInfo ) {
if( pInfo->cutDefault )
cut.init( pInfo->cutDefault );
// FIXME: if there is no cutDefault, then this we be made the primary
// instead of alternate shortcut.
if( pInfo->cutDefault3B )
cut.append( KKey(pInfo->cutDefault3B) );
}
return cut;
}
KShortcut shortcutDefault4( StdAccel id )
{
KShortcut cut;
KStdAccelInfo* pInfo = infoPtr( id );
if( pInfo ) {
KStdAccelInfo& info = *pInfo;
KKeySequence key2;
cut.init( (info.cutDefault4) ?
TQKeySequence(info.cutDefault) : TQKeySequence(info.cutDefault4) );
if( info.cutDefault4B )
key2.init( TQKeySequence(info.cutDefault4B) );
else if( info.cutDefault3B )
key2.init( TQKeySequence(info.cutDefault3B) );
if( key2.count() )
cut.append( key2 );
}
return cut;
}
#if 0 // unused
void createAccelActions( KAccelActions& actions )
{
actions.clear();
for( uint i = 0; g_infoStdAccel[i].psName != 0; i++ ) {
StdAccel id = g_infoStdAccel[i].id;
KStdAccelInfo* pInfo = &g_infoStdAccel[i];
if( id != AccelNone ) {
actions.insert( pInfo->psName,
i18n((pInfo->psDesc) ? pInfo->psDesc : pInfo->psName),
TQString::null, // pInfo->psWhatsThis,
shortcutDefault3(id),
shortcutDefault4(id) );
} else
actions.insert( pInfo->psName, i18n(pInfo->psDesc) );
}
}
#endif
const KShortcut& open() { return shortcut( Open ); }
const KShortcut& openNew() { return shortcut( New ); }
const KShortcut& close() { return shortcut( Close ); }
const KShortcut& save() { return shortcut( Save ); }
const KShortcut& print() { return shortcut( Print ); }
const KShortcut& quit() { return shortcut( Quit ); }
const KShortcut& cut() { return shortcut( Cut ); }
const KShortcut& copy() { return shortcut( Copy ); }
const KShortcut& paste() { return shortcut( Paste ); }
const KShortcut& pasteSelection() { return shortcut( PasteSelection ); }
const KShortcut& deleteWordBack() { return shortcut( DeleteWordBack ); }
const KShortcut& deleteWordForward() { return shortcut( DeleteWordForward ); }
const KShortcut& undo() { return shortcut( Undo ); }
const KShortcut& redo() { return shortcut( Redo ); }
const KShortcut& find() { return shortcut( Find ); }
const KShortcut& findNext() { return shortcut( FindNext ); }
const KShortcut& findPrev() { return shortcut( FindPrev ); }
const KShortcut& replace() { return shortcut( Replace ); }
const KShortcut& home() { return shortcut( Home ); }
const KShortcut& end() { return shortcut( End ); }
const KShortcut& beginningOfLine() { return shortcut( BeginningOfLine ); }
const KShortcut& endOfLine() { return shortcut( EndOfLine ); }
const KShortcut& prior() { return shortcut( Prior ); }
const KShortcut& next() { return shortcut( Next ); }
const KShortcut& backwardWord() { return shortcut( BackwardWord ); }
const KShortcut& forwardWord() { return shortcut( ForwardWord ); }
const KShortcut& gotoLine() { return shortcut( GotoLine ); }
const KShortcut& addBookmark() { return shortcut( AddBookmark ); }
const KShortcut& tabNext() { return shortcut( TabNext ); }
const KShortcut& tabPrev() { return shortcut( TabPrev ); }
const KShortcut& fullScreen() { return shortcut( FullScreen ); }
const KShortcut& zoomIn() { return shortcut( ZoomIn ); }
const KShortcut& zoomOut() { return shortcut( ZoomOut ); }
const KShortcut& help() { return shortcut( Help ); }
const KShortcut& completion() { return shortcut( TextCompletion ); }
const KShortcut& prevCompletion() { return shortcut( PrevCompletion ); }
const KShortcut& nextCompletion() { return shortcut( NextCompletion ); }
const KShortcut& rotateUp() { return shortcut( RotateUp ); }
const KShortcut& rotateDown() { return shortcut( RotateDown ); }
const KShortcut& substringCompletion() { return shortcut( SubstringCompletion ); }
const KShortcut& popupMenuContext() { return shortcut( PopupMenuContext ); }
const KShortcut& whatsThis() { return shortcut( WhatsThis ); }
const KShortcut& reload() { return shortcut( Reload ); }
const KShortcut& selectAll() { return shortcut( SelectAll ); }
const KShortcut& up() { return shortcut( Up ); }
const KShortcut& back() { return shortcut( Back ); }
const KShortcut& forward() { return shortcut( Forward ); }
const KShortcut& showMenubar() { return shortcut( ShowMenubar ); }
//---------------------------------------------------------------------
// ShortcutList
//---------------------------------------------------------------------
ShortcutList::ShortcutList()
{ }
ShortcutList::~ShortcutList()
{ }
uint ShortcutList::count() const
{
static uint g_nAccels = 0;
if( g_nAccels == 0 ) {
for( ; g_infoStdAccel[g_nAccels].psName != 0; g_nAccels++ )
;
}
return g_nAccels;
}
TQString ShortcutList::name( uint i ) const
{ return g_infoStdAccel[i].psName; }
TQString ShortcutList::label( uint i ) const
{ return i18n((g_infoStdAccel[i].psDesc) ? g_infoStdAccel[i].psDesc : g_infoStdAccel[i].psName); }
TQString ShortcutList::whatsThis( uint ) const
{ return TQString::null; }
const KShortcut& ShortcutList::shortcut( uint i ) const
{
if( !g_infoStdAccel[i].bInitialized )
initialize( g_infoStdAccel[i].id );
return g_infoStdAccel[i].cut;
}
const KShortcut& ShortcutList::shortcutDefault( uint i ) const
{
static KShortcut cut;
cut = KStdAccel::shortcutDefault( g_infoStdAccel[i].id );
return cut;
}
bool ShortcutList::isConfigurable( uint i ) const
{ return (g_infoStdAccel[i].id != AccelNone); }
bool ShortcutList::setShortcut( uint i, const KShortcut& cut )
{ g_infoStdAccel[i].cut = cut; return true; }
TQVariant ShortcutList::getOther( Other, uint ) const
{ return TQVariant(); }
bool ShortcutList::setOther( Other, uint, TQVariant )
{ return false; }
bool ShortcutList::save() const
{
return writeSettings( TQString::null, 0, false, true );
}
TDECORE_EXPORT TQString action(StdAccel id)
{ return name(id); }
TDECORE_EXPORT TQString description(StdAccel id)
{ return label(id); }
TDECORE_EXPORT int key(StdAccel id)
{ return shortcut(id).keyCodeQt(); }
TDECORE_EXPORT int defaultKey(StdAccel id)
{ return shortcutDefault(id).keyCodeQt(); }
TDECORE_EXPORT bool isEqual(const TQKeyEvent* ev, int keyQt)
{
KKey key1( ev ), key2( keyQt );
return key1 == key2;
}
}
#undef __KSTDACCEL_CPP_