kdeui Library API Documentation

kaccelgen.h

00001 /*  This file is part of the KDE project
00002     Copyright (C) 2000 Keunwoo Lee <klee@cs.washington.edu>
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017 */
00018 // -*- mode: c++; c-basic-offset: 2 -*-
00019 
00020 #include <qmap.h>
00021 #include <qstring.h>
00022 #include <qstringlist.h>
00023 
00075 namespace KAccelGen
00076 {
00077 
00078 // HELPERS
00079 
00083 template <class Iter>
00084 class Deref
00085 {
00086 public:
00087     static QString deref(Iter i) { return *i; }
00088 };
00089 
00094 template <class Iter>
00095 class Deref_Key
00096 {
00097 public:
00098     static QString deref(Iter i) { return i.key(); }
00099 };
00100 
00108 inline bool
00109 isLegalAccelerator(const QString& str, uint index)
00110 {
00111     return index < str.length()
00112         && str[index].isLetterOrNumber();
00113 }
00114 
00123 template <class Iter, class Deref>
00124 inline void
00125 loadPredefined(Iter begin, Iter end, QMap<QChar,bool>& keys)
00126 {
00127     for (Iter i = begin; i != end; ++i) {
00128         QString item = Deref::deref(i);
00129         int user_ampersand = item.find(QChar('&'));
00130         if( user_ampersand >= 0 ) {
00131             // Sanity check.  Note that we don't try to find an
00132             // accelerator if the user shoots him/herself in the foot
00133             // by adding a bad '&'.
00134             if( isLegalAccelerator(item, user_ampersand+1) ) {
00135                 keys.insert(item[user_ampersand+1], true);
00136             }
00137         }
00138     }
00139 }
00140 
00141 
00142 // ///////////////////////////////////////////////////////////////////
00143 // MAIN USER FUNCTIONS
00144 
00145 
00160 template <class Iter, class Iter_Deref >
00161 void
00162 generate(Iter begin, Iter end, QStringList& target)
00163 {
00164     // Will keep track of used accelerator chars
00165     QMap<QChar,bool> used_accels;
00166 
00167     // Prepass to detect manually user-coded accelerators
00168     loadPredefined<Iter,Iter_Deref>(begin, end, used_accels);
00169 
00170     // Main pass
00171     for (Iter i = begin; i != end; ++i) {
00172         QString item = Iter_Deref::deref(i);
00173 
00174         // Attempt to find a good accelerator, but only if the user
00175         // has not manually hardcoded one.
00176         int user_ampersand = item.find(QChar('&'));
00177         if( user_ampersand < 0 ) {
00178             bool found = false;
00179             uint found_idx;
00180             uint j;
00181 
00182             // Check word-starting letters first.
00183             for( j=0; j < item.length(); ++j ) {
00184                 if( isLegalAccelerator(item, j)
00185                     && !used_accels.contains(item[j])
00186                     && (0 == j || j > 0 && item[j-1].isSpace()) ) {
00187                     found = true;
00188                     found_idx = j;
00189                     break;
00190                 }
00191             }
00192 
00193             if( !found ) {
00194                 // No word-starting letter; search for any letter.
00195                 for( j=0; j < item.length(); ++j ) {
00196                     if( isLegalAccelerator(item, j)
00197                         && !used_accels.contains(item[j]) ) {
00198                         found = true;
00199                         found_idx = j;
00200                         break;
00201                     }
00202                 }
00203             }
00204 
00205             if( found ) {
00206                 // Both upper and lower case marked as used
00207                 used_accels.insert(item[j].upper(),true);
00208                 used_accels.insert(item[j].lower(),true);
00209                 item.insert(j,QChar('&'));
00210             }
00211         }
00212 
00213         target.append( item );
00214     }
00215 }
00216 
00225 template <class Iter>
00226 inline void
00227 generateFromKeys(Iter begin, Iter end, QStringList& target)
00228 {
00229     generate< Iter, Deref_Key<Iter> >(begin, end, target);
00230 }
00231 
00232 
00239 inline void
00240 generate(const QStringList& source, QStringList& target)
00241 {
00242     generate<QStringList::ConstIterator, Deref<QStringList::ConstIterator> >(source.begin(), source.end(), target);
00243 }
00244 
00251 template <class Key>
00252 inline void
00253 generateFromValues(const QMap<Key,QString>& source, QStringList& target)
00254 {
00255     generate<QMapConstIterator<Key,QString>, Deref_Key<QMapConstIterator<Key,QString> > >(source.begin(), source.end(), target);
00256 }
00257 
00264 template <class Data>
00265 inline void
00266 generateFromKeys(const QMap<QString,Data>& source, QStringList& target)
00267 {
00268     generateFromKeys(source.begin(), source.end(), target);
00269 }
00270 
00271 
00272 } // end namespace KAccelGen
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.0.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Wed Oct 8 12:20:56 2003 by doxygen 1.2.18 written by Dimitri van Heesch, © 1997-2001