/* 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 #include #include #include #include #include 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_