libyui
3.0.10
|
00001 /* 00002 Copyright (C) 2000-2012 Novell, Inc 00003 This library is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU Lesser General Public License as 00005 published by the Free Software Foundation; either version 2.1 of the 00006 License, or (at your option) version 3.0 of the License. This library 00007 is distributed in the hope that it will be useful, but WITHOUT ANY 00008 WARRANTY; without even the implied warranty of MERCHANTABILITY or 00009 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00010 License for more details. You should have received a copy of the GNU 00011 Lesser General Public License along with this library; if not, write 00012 to the Free Software Foundation, Inc., 51 Franklin Street, Fifth 00013 Floor, Boston, MA 02110-1301 USA 00014 */ 00015 00016 00017 /*-/ 00018 00019 File: YShortcutManager.h 00020 00021 Author: Stefan Hundhammer <sh@suse.de> 00022 00023 /-*/ 00024 00025 00026 #ifndef YShortcutManager_h 00027 #define YShortcutManager_h 00028 00029 #include "YWidget.h" 00030 #include "YShortcut.h" 00031 00032 class YDialog; 00033 00034 /** 00035 * Helper class to manage keyboard shortcuts within one dialog and resolve 00036 * keyboard shortcut conflicts. 00037 **/ 00038 class YShortcutManager 00039 { 00040 public: 00041 /** 00042 * Constructor. 00043 **/ 00044 YShortcutManager( YDialog *dialog ); 00045 00046 /** 00047 * Destructor 00048 **/ 00049 virtual ~YShortcutManager(); 00050 00051 /** 00052 * Check the keyboard shortcuts of all children of this dialog 00053 * (not for sub-dialogs!). 00054 * 00055 * Call resolveAllConflicts() if 'autoResolve' is 'true'. 00056 **/ 00057 void checkShortcuts( bool autoResolve = true ); 00058 00059 /** 00060 * Returns the number of shortcut conflicts. 00061 * Valid only after checkShortcuts() or resolveAllConflicts(). 00062 **/ 00063 int conflictCount() { return _conflictCount; } 00064 00065 /** 00066 * Resolve shortcut conflicts. Requires checkShortcuts() to be called first. 00067 * 00068 * Note: This may or may not work. There is no general solution to that 00069 * problem. This method tries its best, but you may end up with widgets 00070 * that don't have any ( more ) shortcut. 00071 * 00072 * Why? Just picture the following ( admittedly pathologic ) situation: 00073 * 00074 * [& OK] 00075 * [& OK] 00076 * [& OK] 00077 * 00078 * This will result in something like this: 00079 * 00080 * [& OK] 00081 * [O& K] 00082 * [OK] 00083 * 00084 * I.e. the first OK button will retain its preferred shortcut ( 'O' ), the 00085 * second OK button's shortcut will be reassigned to 'K' and the third 00086 * won't get any - there are simply not enough eligible shortcut 00087 * characters. 00088 * 00089 * This may even fail in much less pathological situations. This example is 00090 * only supposed to give you a general idea why not to blindly rely on 00091 * automatic shortcut resolving. 00092 * 00093 * It's always best to resolve conflicts manually. This will generally 00094 * result in much better shortcuts: Easier to memorize, less chance of 00095 * picking characters that cannot really do a good job showing their 00096 * shortcut like very narrow characters ( .e.g., 'i' ) or descender 00097 * characters ( e.g., 'g', 'p', 'q' - imagine those underlined! ). 00098 **/ 00099 void resolveAllConflicts(); 00100 00101 /** 00102 * Returns the dialog this shortcut manager works on. 00103 **/ 00104 YDialog *dialog() { return _dialog; } 00105 00106 protected: 00107 00108 /** 00109 * Delete all members of the internal shortcut list, then empty the list. 00110 **/ 00111 void clearShortcutList(); 00112 00113 /** 00114 * Recursively search all widgets between iterators 'begin' and 'end' (not 00115 * those of any sub-dialogs!) for child widgets that could accept a 00116 * keyboard shortcut and add these to _shortcutList. 00117 **/ 00118 void findShortcutWidgets( YWidgetListConstIterator begin, 00119 YWidgetListConstIterator end ); 00120 00121 /** 00122 * Pick a new shortcut character for 'shortcut' - one that isn't marked as 00123 * used in the '_used' array. Unset the conflict marker if that succeeded. 00124 **/ 00125 void resolveConflict( YShortcut * shortcut ); 00126 00127 /** 00128 * Find the shortest wizard button in 'conflictList', if there is any. 00129 * Returns the index of that shortest wizard button or -1 if there is none. 00130 **/ 00131 int findShortestWizardButton( const YShortcutList & conflictList ); 00132 00133 /** 00134 * Find the shortest widget in 'conflictList'. Buttons get priority if they 00135 * have the same number of eligible shortcut characters as another widget. 00136 * 00137 * Returns the index of the shortest widget. 00138 **/ 00139 unsigned findShortestWidget( const YShortcutList & conflictList ); 00140 00141 /** 00142 * The dialog this shortcut manager works on. 00143 **/ 00144 YDialog *_dialog; 00145 00146 /** 00147 * List of all the shortcuts in this dialog. 00148 **/ 00149 YShortcutList _shortcutList; 00150 00151 /** 00152 * Counters for wanted shortcut characters. 00153 **/ 00154 int _wanted[ sizeof( char ) << 8 ]; 00155 00156 00157 /** 00158 * Flags for used shortcut characters. 00159 **/ 00160 bool _used[ sizeof( char ) << 8 ]; 00161 00162 00163 /** 00164 * Counter for shortcut conflicts 00165 **/ 00166 int _conflictCount; 00167 00168 00169 private: 00170 00171 bool _didCheck; 00172 }; 00173 00174 00175 #endif // YShortcutManager_h