kdecore Library API Documentation

kaccelmanager.cpp

00001 /* This file is part of the KDE project 00002 Copyright (C) 2002 Matthias Hölzer-Klüpfel <mhk@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library 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 GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 Boston, MA 02111-1307, USA. 00018 */ 00019 00020 00021 #include <qwidget.h> 00022 #include <qobjectlist.h> 00023 #include <qapplication.h> 00024 #include <qpopupmenu.h> 00025 #include <qmenubar.h> 00026 #include <qmemarray.h> 00027 #include <qmainwindow.h> 00028 #include <qtabbar.h> 00029 #include <qwidgetstack.h> 00030 #include <qlabel.h> 00031 #include <qptrlist.h> 00032 #include <qmetaobject.h> 00033 #include <kstdaction.h> 00034 #include <kstaticdeleter.h> 00035 #include <kdebug.h> 00036 00037 00038 #include "kaccelmanager_private.h" 00039 #include "../kdeui/kstdaction_p.h" 00040 00041 #include "kaccelmanager.h" 00042 00043 // Default control weight 00044 const int KAccelManagerAlgorithm::DEFAULT_WEIGHT = 50; 00045 // Additional weight for first character in string 00046 const int KAccelManagerAlgorithm::FIRST_CHARACTER_EXTRA_WEIGHT = 50; 00047 // Additional weight for the beginning of a word 00048 const int KAccelManagerAlgorithm::WORD_BEGINNING_EXTRA_WEIGHT = 50; 00049 // Additional weight for the dialog buttons (large, we basically never want these reassigned) 00050 const int KAccelManagerAlgorithm::DIALOG_BUTTON_EXTRA_WEIGHT = 300; 00051 // Additional weight for a 'wanted' accelerator 00052 const int KAccelManagerAlgorithm::WANTED_ACCEL_EXTRA_WEIGHT = 150; 00053 // Default weight for an 'action' widget (ie, pushbuttons) 00054 const int KAccelManagerAlgorithm::ACTION_ELEMENT_WEIGHT = 50; 00055 // Default weight for group boxes (low priority) 00056 const int KAccelManagerAlgorithm::GROUP_BOX_WEIGHT = 0; 00057 // Default weight for menu titles 00058 const int KAccelManagerAlgorithm::MENU_TITLE_WEIGHT = 250; 00059 // Additional weight for KDE standard accelerators 00060 const int KAccelManagerAlgorithm::STANDARD_ACCEL = 300; 00061 00062 /********************************************************************* 00063 00064 class Item - helper class containing widget information 00065 00066 This class stores information about the widgets the need accelerators, 00067 as well as about their relationship. 00068 00069 *********************************************************************/ 00070 00071 00072 00073 /********************************************************************* 00074 00075 class KAcceleratorManagerPrivate - internal helper class 00076 00077 This class does all the work to find accelerators for a hierarchy of 00078 widgets. 00079 00080 *********************************************************************/ 00081 00082 00083 class KAcceleratorManagerPrivate 00084 { 00085 public: 00086 00087 static void manage(QWidget *widget); 00088 static bool programmers_mode; 00089 static bool standardName(const QString &str); 00090 00091 static bool checkChange(const KAccelString &as) { 00092 QString t2 = as.accelerated(); 00093 QString t1 = as.originalText(); 00094 if (t1 != t2) 00095 { 00096 if (as.accel() == -1) { 00097 removed_string += "<tr><td>" + t1 + "</td></tr>"; 00098 } else if (as.originalAccel() == -1) { 00099 added_string += "<tr><td>" + t2 + "</td></tr>"; 00100 } else { 00101 changed_string += "<tr><td>" + t1 + "</td>"; 00102 changed_string += "<td>" + t2 + "</td></tr>"; 00103 } 00104 return true; 00105 } 00106 return false; 00107 } 00108 static QString changed_string; 00109 static QString added_string; 00110 static QString removed_string; 00111 00112 private: 00113 class Item; 00114 typedef QPtrList<Item> ItemList; 00115 00116 00117 static void traverseChildren(QWidget *widget, Item *item); 00118 00119 static void manageWidget(QWidget *widget, Item *item); 00120 static void manageMenuBar(QMenuBar *mbar, Item *item); 00121 static void manageTabBar(QTabBar *bar, Item *item); 00122 00123 static void calculateAccelerators(Item *item, QString &used); 00124 00125 class Item 00126 { 00127 public: 00128 00129 Item() : m_widget(0), m_children(0), m_index(-1) {}; 00130 ~Item(); 00131 00132 void addChild(Item *item); 00133 00134 QWidget *m_widget; 00135 KAccelString m_content; 00136 ItemList *m_children; 00137 int m_index; 00138 00139 }; 00140 }; 00141 00142 00143 bool KAcceleratorManagerPrivate::programmers_mode = false; 00144 QString KAcceleratorManagerPrivate::changed_string; 00145 QString KAcceleratorManagerPrivate::added_string; 00146 QString KAcceleratorManagerPrivate::removed_string; 00147 static QStringList *kaccmp_sns = 0; 00148 static KStaticDeleter<QStringList> kaccmp_sns_d; 00149 00150 bool KAcceleratorManagerPrivate::standardName(const QString &str) 00151 { 00152 if (!kaccmp_sns) 00153 kaccmp_sns_d.setObject(kaccmp_sns, new QStringList(KStdAction::internal_stdNames())); 00154 return kaccmp_sns->contains(str); 00155 } 00156 00157 KAcceleratorManagerPrivate::Item::~Item() 00158 { 00159 delete m_children; 00160 } 00161 00162 00163 void KAcceleratorManagerPrivate::Item::addChild(Item *item) 00164 { 00165 if (!m_children) { 00166 m_children = new ItemList; 00167 m_children->setAutoDelete(true); 00168 } 00169 00170 m_children->append(item); 00171 } 00172 00173 void KAcceleratorManagerPrivate::manage(QWidget *widget) 00174 { 00175 if (widget->inherits("QPopupMenu")) 00176 { 00177 // create a popup accel manager that can deal with dynamic menus 00178 KPopupAccelManager::manage(static_cast<QPopupMenu*>(widget)); 00179 return; 00180 } 00181 00182 Item *root = new Item; 00183 00184 manageWidget(widget, root); 00185 00186 QString used; 00187 calculateAccelerators(root, used); 00188 delete root; 00189 } 00190 00191 00192 void KAcceleratorManagerPrivate::calculateAccelerators(Item *item, QString &used) 00193 { 00194 if (!item->m_children) 00195 return; 00196 00197 // collect the contents 00198 KAccelStringList contents; 00199 for (Item *it = item->m_children->first(); it != 0; 00200 it = item->m_children->next()) 00201 { 00202 contents << it->m_content; 00203 } 00204 00205 // find the right accelerators 00206 KAccelManagerAlgorithm::findAccelerators(contents, used); 00207 00208 // write them back into the widgets 00209 int cnt = -1; 00210 for (Item *it = item->m_children->first(); it != 0; 00211 it = item->m_children->next()) 00212 { 00213 cnt++; 00214 00215 if (it->m_widget->inherits("QTabBar")) 00216 { 00217 QTabBar *bar = static_cast<QTabBar*>(it->m_widget); 00218 if (checkChange(contents[cnt])) 00219 bar->tabAt(it->m_index)->setText(contents[cnt].accelerated()); 00220 continue; 00221 } 00222 if (it->m_widget->inherits("QMenuBar")) 00223 { 00224 QMenuBar *bar = static_cast<QMenuBar*>(it->m_widget); 00225 if (it->m_index >= 0) 00226 { 00227 QMenuItem *mitem = bar->findItem(bar->idAt(it->m_index)); 00228 if (mitem) 00229 { 00230 checkChange(contents[cnt]); 00231 mitem->setText(contents[cnt].accelerated()); 00232 } 00233 continue; 00234 } 00235 } 00236 int tprop = it->m_widget->metaObject()->findProperty("text", true); 00237 if (tprop != -1) { 00238 if (checkChange(contents[cnt])) 00239 it->m_widget->setProperty("text", contents[cnt].accelerated()); 00240 } else { 00241 tprop = it->m_widget->metaObject()->findProperty("title", true); 00242 if (tprop != -1 && checkChange(contents[cnt])) 00243 it->m_widget->setProperty("title", contents[cnt].accelerated()); 00244 } 00245 } 00246 00247 // calculate the accelerators for the children 00248 for (Item *it = item->m_children->first(); it != 0; 00249 it = item->m_children->next()) 00250 { 00251 if (it->m_widget && it->m_widget->isVisibleTo( item->m_widget )) 00252 calculateAccelerators(it, used); 00253 } 00254 } 00255 00256 00257 void KAcceleratorManagerPrivate::traverseChildren(QWidget *widget, Item *item) 00258 { 00259 QObjectList *childList = widget->queryList("QWidget", 0, false, false); 00260 for ( QObject *it = childList->first(); it; it = childList->next() ) 00261 { 00262 QWidget *w = static_cast<QWidget*>(it); 00263 00264 if ( !w->isVisibleTo( widget ) ) 00265 continue; 00266 00267 manageWidget(w, item); 00268 } 00269 delete childList; 00270 } 00271 00272 void KAcceleratorManagerPrivate::manageWidget(QWidget *w, Item *item) 00273 { 00274 // first treat the special cases 00275 00276 if (w->inherits("QTabBar")) 00277 { 00278 manageTabBar(static_cast<QTabBar*>(w), item); 00279 return; 00280 } 00281 00282 if (w->inherits("QPopupMenu")) 00283 { 00284 // create a popup accel manager that can deal with dynamic menus 00285 KPopupAccelManager::manage(static_cast<QPopupMenu*>(w)); 00286 return; 00287 } 00288 00289 if (w->inherits("QMenuBar")) 00290 { 00291 manageMenuBar(static_cast<QMenuBar*>(w), item); 00292 return; 00293 } 00294 00295 if (w->inherits("QComboBox") || w->inherits("QLineEdit") || 00296 w->inherits("QTextEdit") || w->inherits("QTextView") || 00297 w->inherits("QSpinBox")) 00298 return; 00299 00300 // now treat 'ordinary' widgets 00301 if (w->isFocusEnabled() || (w->inherits("QLabel") && static_cast<QLabel*>(w)->buddy()) || w->inherits("QGroupBox")) 00302 { 00303 QString content; 00304 QVariant variant; 00305 int tprop = w->metaObject()->findProperty("text", true); 00306 if (tprop != -1) { 00307 const QMetaProperty* p = w->metaObject()->property( tprop, true ); 00308 if ( p && p->isValid() ) 00309 w->qt_property( tprop, 1, &variant ); 00310 else 00311 tprop = -1; 00312 } 00313 00314 if (tprop == -1) { 00315 tprop = w->metaObject()->findProperty("title", true); 00316 if (tprop != -1) { 00317 const QMetaProperty* p = w->metaObject()->property( tprop, true ); 00318 if ( p && p->isValid() ) 00319 w->qt_property( tprop, 1, &variant ); 00320 } 00321 } 00322 00323 if (variant.isValid()) 00324 content = variant.toString(); 00325 00326 if (!content.isEmpty()) 00327 { 00328 Item *i = new Item; 00329 i->m_widget = w; 00330 00331 // put some more weight on the usual action elements 00332 int weight = KAccelManagerAlgorithm::DEFAULT_WEIGHT; 00333 if (w->inherits("QPushButton") || w->inherits("QCheckBox") || w->inherits("QRadioButton") || w->inherits("QLabel")) 00334 weight = KAccelManagerAlgorithm::ACTION_ELEMENT_WEIGHT; 00335 00336 // don't put weight on group boxes, as usually the contents are more important 00337 if (w->inherits("QGroupBox")) 00338 weight = KAccelManagerAlgorithm::GROUP_BOX_WEIGHT; 00339 00340 // put a lot of extra weight on the KDialogBaseButton's 00341 if (w->inherits("KDialogBaseButton")) 00342 weight += KAccelManagerAlgorithm::DIALOG_BUTTON_EXTRA_WEIGHT; 00343 00344 i->m_content = KAccelString(content, weight); 00345 item->addChild(i); 00346 } 00347 } 00348 traverseChildren(w, item); 00349 } 00350 00351 void KAcceleratorManagerPrivate::manageTabBar(QTabBar *bar, Item *item) 00352 { 00353 for (int i=0; i<bar->count(); i++) 00354 { 00355 QString content = bar->tabAt(i)->text(); 00356 if (content.isEmpty()) 00357 continue; 00358 00359 Item *it = new Item; 00360 item->addChild(it); 00361 it->m_widget = bar; 00362 it->m_index = i; 00363 it->m_content = KAccelString(content); 00364 } 00365 } 00366 00367 00368 void KAcceleratorManagerPrivate::manageMenuBar(QMenuBar *mbar, Item *item) 00369 { 00370 QMenuItem *mitem; 00371 QString s; 00372 00373 for (uint i=0; i<mbar->count(); ++i) 00374 { 00375 mitem = mbar->findItem(mbar->idAt(i)); 00376 if (!mitem) 00377 continue; 00378 00379 // nothing to do for separators 00380 if (mitem->isSeparator()) 00381 continue; 00382 00383 s = mitem->text(); 00384 if (!s.isEmpty()) 00385 { 00386 Item *it = new Item; 00387 item->addChild(it); 00388 it->m_content = 00389 KAccelString(s, 00390 // menu titles are important, so raise the weight 00391 KAccelManagerAlgorithm::MENU_TITLE_WEIGHT); 00392 00393 it->m_widget = mbar; 00394 it->m_index = i; 00395 } 00396 00397 // have a look at the popup as well, if present 00398 if (mitem->popup()) 00399 KPopupAccelManager::manage(mitem->popup()); 00400 } 00401 } 00402 00403 00404 /********************************************************************* 00405 00406 class KAcceleratorManager - main entry point 00407 00408 This class is just here to provide a clean public API... 00409 00410 *********************************************************************/ 00411 00412 void KAcceleratorManager::manage(QWidget *widget) 00413 { 00414 KAcceleratorManager::manage(widget, false); 00415 } 00416 00417 void KAcceleratorManager::manage(QWidget *widget, bool programmers_mode) 00418 { 00419 KAcceleratorManagerPrivate::changed_string = QString::null; 00420 KAcceleratorManagerPrivate::added_string = QString::null; 00421 KAcceleratorManagerPrivate::removed_string = QString::null; 00422 KAcceleratorManagerPrivate::programmers_mode = programmers_mode; 00423 KAcceleratorManagerPrivate::manage(widget); 00424 } 00425 00426 void KAcceleratorManager::last_manage(QString &added, QString &changed, QString &removed) 00427 { 00428 added = KAcceleratorManagerPrivate::added_string; 00429 changed = KAcceleratorManagerPrivate::changed_string; 00430 removed = KAcceleratorManagerPrivate::removed_string; 00431 } 00432 00433 00434 /********************************************************************* 00435 00436 class KAccelString - a string with weighted characters 00437 00438 *********************************************************************/ 00439 00440 KAccelString::KAccelString(const QString &input, int initialWeight) 00441 : m_pureText(input), m_weight() 00442 { 00443 if (m_pureText.contains('\t')) 00444 m_pureText = m_pureText.left(m_pureText.find('\t')); 00445 m_origText = m_pureText; 00446 m_orig_accel = m_pureText.find("(!)&"); 00447 m_pureText.replace(m_orig_accel, 4, ""); 00448 m_orig_accel = m_pureText.find("(&&)"); 00449 if (m_orig_accel != -1) 00450 m_pureText.replace(m_orig_accel, 4, "&"); 00451 m_orig_accel = m_accel = stripAccelerator(m_pureText); 00452 00453 kdDebug(125) << input << " " << m_orig_accel << " " << m_accel << " " << m_pureText << endl; 00454 if (initialWeight == -1) 00455 initialWeight = KAccelManagerAlgorithm::DEFAULT_WEIGHT; 00456 00457 calculateWeights(initialWeight); 00458 00459 // dump(); 00460 } 00461 00462 00463 QString KAccelString::accelerated() const 00464 { 00465 QString result = m_pureText; 00466 if (result.isEmpty()) 00467 return result; 00468 00469 if (KAcceleratorManagerPrivate::programmers_mode) 00470 { 00471 int oa = m_orig_accel; 00472 00473 if (m_accel >= 0) { 00474 if (m_accel != m_orig_accel) { 00475 result.insert(m_accel, "(!)&"); 00476 if (m_accel < m_orig_accel) 00477 oa += 4; 00478 } else { 00479 result.insert(m_accel, "&"); 00480 if (m_accel < m_orig_accel) 00481 oa++; 00482 } 00483 } 00484 00485 if (m_accel != m_orig_accel && m_orig_accel >= 0) 00486 result.insert(oa, "(&&)"); 00487 } else { 00488 if (m_accel >= 0) 00489 result.insert(m_accel, "&"); 00490 } 00491 return result; 00492 } 00493 00494 00495 QChar KAccelString::accelerator() const 00496 { 00497 if ((m_accel < 0) || (m_accel > (int)m_pureText.length())) 00498 return QChar(); 00499 00500 return m_pureText[m_accel].lower(); 00501 } 00502 00503 00504 void KAccelString::calculateWeights(int initialWeight) 00505 { 00506 m_weight.resize(m_pureText.length()); 00507 00508 uint pos = 0; 00509 bool start_character = true; 00510 00511 while (pos<m_pureText.length()) 00512 { 00513 QChar c = m_pureText[pos]; 00514 00515 int weight = initialWeight+1; 00516 00517 // add special weight to first character 00518 if (pos == 0) 00519 weight += KAccelManagerAlgorithm::FIRST_CHARACTER_EXTRA_WEIGHT; 00520 00521 // add weight to word beginnings 00522 if (start_character) 00523 { 00524 weight += KAccelManagerAlgorithm::WORD_BEGINNING_EXTRA_WEIGHT; 00525 start_character = false; 00526 } 00527 00528 // add decreasing weight to left characters 00529 if (pos < 50) 00530 weight += (50-pos); 00531 00532 // try to preserve the wanted accelarators 00533 if ((int)pos == accel()) { 00534 weight += KAccelManagerAlgorithm::WANTED_ACCEL_EXTRA_WEIGHT; 00535 // kdDebug() << "wanted " << m_pureText << " " << KAcceleratorManagerPrivate::standardName(m_origText) << endl; 00536 if (KAcceleratorManagerPrivate::standardName(m_origText)) { 00537 weight += KAccelManagerAlgorithm::STANDARD_ACCEL; 00538 } 00539 } 00540 00541 // skip non typeable characters 00542 if (!c.isLetterOrNumber()) 00543 { 00544 weight = 0; 00545 start_character = true; 00546 } 00547 00548 m_weight[pos] = weight; 00549 00550 ++pos; 00551 } 00552 } 00553 00554 00555 int KAccelString::stripAccelerator(QString &text) 00556 { 00557 // Note: this code is derived from QAccel::shortcutKey 00558 int p = 0; 00559 00560 while (p >= 0) 00561 { 00562 p = text.find('&', p)+1; 00563 00564 if (p <= 0 || p >= (int)text.length()) 00565 return -1; 00566 00567 if (text[p] != '&') 00568 { 00569 QChar c = text[p]; 00570 if (c.isPrint()) 00571 { 00572 text.remove(p-1,1); 00573 return p-1; 00574 } 00575 } 00576 00577 p++; 00578 } 00579 00580 return -1; 00581 } 00582 00583 00584 int KAccelString::maxWeight(int &index, const QString &used) 00585 { 00586 int max = 0; 00587 index = -1; 00588 00589 for (uint pos=0; pos<m_pureText.length(); ++pos) 00590 if (used.find(m_pureText[pos], 0, FALSE) == -1 && m_pureText[pos].latin1() != 0) 00591 if (m_weight[pos] > max) 00592 { 00593 max = m_weight[pos]; 00594 index = pos; 00595 } 00596 00597 return max; 00598 } 00599 00600 00601 void KAccelString::dump() 00602 { 00603 QString s; 00604 for (uint i=0; i<m_weight.count(); ++i) 00605 s += QString("%1(%2) ").arg(pure()[i]).arg(m_weight[i]); 00606 kdDebug() << "s " << s << endl; 00607 } 00608 00609 00610 /********************************************************************* 00611 00612 findAccelerators - the algorithm determining the new accelerators 00613 00614 The algorithm is very crude: 00615 00616 * each character in each widget text is assigned a weight 00617 * the character with the highest weight over all is picked 00618 * that widget is removed from the list 00619 * the weights are recalculated 00620 * the process is repeated until no more accelerators can be found 00621 00622 The algorithm has some advantages: 00623 00624 * it favors 'nice' accelerators (first characters in a word, etc.) 00625 * it is quite fast, O(N²) 00626 * it is easy to understand :-) 00627 00628 The disadvantages: 00629 00630 * it does not try to find as many accelerators as possible 00631 00632 TODO: 00633 00634 * The result is always correct, but not neccesarily optimal. Perhaps 00635 it would be a good idea to add another algorithm with higher complexity 00636 that gets used when this one fails, i.e. leaves widgets without 00637 accelerators. 00638 00639 * The weights probably need some tweaking so they make more sense. 00640 00641 *********************************************************************/ 00642 00643 void KAccelManagerAlgorithm::findAccelerators(KAccelStringList &result, QString &used) 00644 { 00645 KAccelStringList accel_strings = result; 00646 00647 // initally remove all accelerators 00648 for (KAccelStringList::Iterator it = result.begin(); it != result.end(); ++it) 00649 (*it).setAccel(-1); 00650 00651 // pick the highest bids 00652 for (uint cnt=0; cnt<accel_strings.count(); ++cnt) 00653 { 00654 int max = 0, index = -1, accel = -1; 00655 00656 // find maximum weight 00657 for (uint i=0; i<accel_strings.count(); ++i) 00658 { 00659 int a; 00660 int m = accel_strings[i].maxWeight(a, used); 00661 if (m>max) 00662 { 00663 max = m; 00664 index = i; 00665 accel = a; 00666 } 00667 } 00668 00669 // stop if no more accelerators can be found 00670 if (index < 0) 00671 return; 00672 00673 // insert the accelerator 00674 if (accel >= 0) 00675 { 00676 result[index].setAccel(accel); 00677 used.append(result[index].accelerator()); 00678 } 00679 00680 // make sure we don't visit this one again 00681 accel_strings[index] = KAccelString(); 00682 } 00683 } 00684 00685 00686 /********************************************************************* 00687 00688 class KPopupAccelManager - managing QPopupMenu widgets dynamically 00689 00690 *********************************************************************/ 00691 00692 KPopupAccelManager::KPopupAccelManager(QPopupMenu *popup) 00693 : QObject(popup), m_popup(popup), m_count(-1) 00694 { 00695 aboutToShow(); // do one check and then connect to show 00696 connect(popup, SIGNAL(aboutToShow()), SLOT(aboutToShow())); 00697 } 00698 00699 00700 void KPopupAccelManager::aboutToShow() 00701 { 00702 // Note: we try to be smart and avoid recalculating the accelerators 00703 // whenever possible. Unfortunately, there is no way to know if an 00704 // item has been added or removed, so we can not do much more than 00705 // to compare the items each time the menu is shown :-( 00706 00707 if (m_count != (int)m_popup->count()) 00708 { 00709 findMenuEntries(m_entries); 00710 calculateAccelerators(); 00711 m_count = m_popup->count(); 00712 } 00713 else 00714 { 00715 KAccelStringList entries; 00716 findMenuEntries(entries); 00717 if (entries != m_entries) 00718 { 00719 m_entries = entries; 00720 calculateAccelerators(); 00721 } 00722 } 00723 } 00724 00725 00726 void KPopupAccelManager::calculateAccelerators() 00727 { 00728 // find the new accelerators 00729 QString used; 00730 KAccelManagerAlgorithm::findAccelerators(m_entries, used); 00731 00732 // change the menu entries 00733 setMenuEntries(m_entries); 00734 } 00735 00736 00737 void KPopupAccelManager::findMenuEntries(KAccelStringList &list) 00738 { 00739 QMenuItem *mitem; 00740 QString s; 00741 00742 list.clear(); 00743 00744 // read out the menu entries 00745 for (uint i=0; i<m_popup->count(); i++) 00746 { 00747 mitem = m_popup->findItem(m_popup->idAt(i)); 00748 if (mitem->isSeparator()) 00749 continue; 00750 00751 s = mitem->text(); 00752 00753 // in full menus, look at entries with global accelerators last 00754 int weight = 50; 00755 if (s.contains('\t')) 00756 weight = 0; 00757 00758 list.append(KAccelString(s, weight)); 00759 00760 // have a look at the popup as well, if present 00761 if (mitem->popup()) 00762 KPopupAccelManager::manage(mitem->popup()); 00763 } 00764 } 00765 00766 00767 void KPopupAccelManager::setMenuEntries(const KAccelStringList &list) 00768 { 00769 QMenuItem *mitem; 00770 00771 uint cnt = 0; 00772 for (uint i=0; i<m_popup->count(); i++) 00773 { 00774 mitem = m_popup->findItem(m_popup->idAt(i)); 00775 if (mitem->isSeparator()) 00776 continue; 00777 00778 if (KAcceleratorManagerPrivate::checkChange(list[cnt])) 00779 mitem->setText(list[cnt].accelerated()); 00780 cnt++; 00781 } 00782 } 00783 00784 00785 void KPopupAccelManager::manage(QPopupMenu *popup) 00786 { 00787 // don't add more than one manager to a popup 00788 if (popup->child(0, "KPopupAccelManager", false) == 0 ) 00789 new KPopupAccelManager(popup); 00790 } 00791 00792 00793 #include "kaccelmanager_private.moc"
KDE Logo
This file is part of the documentation for kdecore Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sun Oct 10 18:54:54 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003