diff options
Diffstat (limited to 'kdecore/kstdaccel.cpp')
-rw-r--r-- | kdecore/kstdaccel.cpp | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/kdecore/kstdaccel.cpp b/kdecore/kstdaccel.cpp new file mode 100644 index 000000000..262535e45 --- /dev/null +++ b/kdecore/kstdaccel.cpp @@ -0,0 +1,396 @@ +/* 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, Qt::Key_Prior, 0, 0, 0, KShortcut(), false }, + { Next, I18N_NOOP2("Opposite to Prior","Next"), 0, Qt::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 ) ) { + QString 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; +} + +QString name( StdAccel id ) +{ + KStdAccelInfo* pInfo = infoPtr( id ); + if( !pInfo ) + return QString::null; + return pInfo->psName; +} + +QString label( StdAccel id ) +{ + KStdAccelInfo* pInfo = infoPtr( id ); + if( !pInfo ) + return QString::null; + return i18n((pInfo->psDesc) ? pInfo->psDesc : pInfo->psName); +} + +// TODO: Add psWhatsThis entry to KStdAccelInfo +QString whatsThis( StdAccel /*id*/ ) +{ +// KStdAccelInfo* pInfo = infoPtr( id ); +// if( pInfo && pInfo->psWhatsThis ) +// return i18n(pInfo->psWhatsThis); +// else + return QString::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) ? + QKeySequence(info.cutDefault) : QKeySequence(info.cutDefault4) ); + + if( info.cutDefault4B ) + key2.init( QKeySequence(info.cutDefault4B) ); + else if( info.cutDefault3B ) + key2.init( QKeySequence(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), + QString::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; +} + +QString ShortcutList::name( uint i ) const + { return g_infoStdAccel[i].psName; } + +QString ShortcutList::label( uint i ) const + { return i18n((g_infoStdAccel[i].psDesc) ? g_infoStdAccel[i].psDesc : g_infoStdAccel[i].psName); } + +QString ShortcutList::whatsThis( uint ) const + { return QString::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; } + +QVariant ShortcutList::getOther( Other, uint ) const + { return QVariant(); } + +bool ShortcutList::setOther( Other, uint, QVariant ) + { return false; } + +bool ShortcutList::save() const +{ + return writeSettings( QString::null, 0, false, true ); +} + +KDECORE_EXPORT QString action(StdAccel id) + { return name(id); } +KDECORE_EXPORT QString description(StdAccel id) + { return label(id); } +KDECORE_EXPORT int key(StdAccel id) + { return shortcut(id).keyCodeQt(); } +KDECORE_EXPORT int defaultKey(StdAccel id) + { return shortcutDefault(id).keyCodeQt(); } + +KDECORE_EXPORT bool isEqual(const QKeyEvent* ev, int keyQt) +{ + KKey key1( ev ), key2( keyQt ); + return key1 == key2; +} + +} + +#undef __KSTDACCEL_CPP_ |