KDEUI
kselectaction.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1999 Reginald Stadlbauer <reggie@kde.org> 00003 (C) 1999 Simon Hausmann <hausmann@kde.org> 00004 (C) 2000 Nicolas Hadacek <haadcek@kde.org> 00005 (C) 2000 Kurt Granroth <granroth@kde.org> 00006 (C) 2000 Michael Koch <koch@kde.org> 00007 (C) 2001 Holger Freyther <freyther@kde.org> 00008 (C) 2002 Ellis Whitehead <ellis@kde.org> 00009 (C) 2002 Joseph Wenninger <jowenn@kde.org> 00010 (C) 2003 Andras Mantia <amantia@kde.org> 00011 (C) 2005-2006 Hamish Rodda <rodda@kde.org> 00012 (C) 2006 Albert Astals Cid <aacid@kde.org> 00013 (C) 2006 Clarence Dang <dang@kde.org> 00014 (C) 2006 Michel Hermier <michel.hermier@gmail.com> 00015 (C) 2007 Nick Shaforostoff <shafff@ukr.net> 00016 00017 This library is free software; you can redistribute it and/or 00018 modify it under the terms of the GNU Library General Public 00019 License version 2 as published by the Free Software Foundation. 00020 00021 This library is distributed in the hope that it will be useful, 00022 but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00024 Library General Public License for more details. 00025 00026 You should have received a copy of the GNU Library General Public License 00027 along with this library; see the file COPYING.LIB. If not, write to 00028 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00029 Boston, MA 02110-1301, USA. 00030 */ 00031 00032 #include "kselectaction.h" 00033 #include "kselectaction_p.h" 00034 00035 #include <QActionEvent> 00036 #include <QEvent> 00037 #include <QToolButton> 00038 #include <QToolBar> 00039 #include <QStandardItem> 00040 #include <kicon.h> 00041 #include <klocale.h> 00042 #include <kdebug.h> 00043 00044 #include "kcombobox.h" 00045 #include "kmenu.h" 00046 00047 // QAction::setText("Hi") and then KPopupAccelManager exec'ing, causes 00048 // QAction::text() to return "&Hi" :( Comboboxes don't have accels and 00049 // display ampersands literally. 00050 static QString DropAmpersands(const QString &text) 00051 { 00052 return KGlobal::locale()->removeAcceleratorMarker(text); 00053 } 00054 00055 00056 KSelectAction::KSelectAction(QObject *parent) 00057 : KAction(parent) 00058 , d_ptr(new KSelectActionPrivate()) 00059 { 00060 Q_D(KSelectAction); 00061 d->init(this); 00062 } 00063 00064 KSelectAction::KSelectAction(const QString &text, QObject *parent) 00065 : KAction(parent) 00066 , d_ptr(new KSelectActionPrivate()) 00067 { 00068 Q_D(KSelectAction); 00069 d->init(this); 00070 setText(text); 00071 } 00072 00073 KSelectAction::KSelectAction(const KIcon & icon, const QString &text, QObject *parent) 00074 : KAction(icon, text, parent) 00075 , d_ptr(new KSelectActionPrivate()) 00076 { 00077 Q_D(KSelectAction); 00078 d->init(this); 00079 } 00080 00081 KSelectAction::KSelectAction(KSelectActionPrivate &dd, QObject *parent) 00082 : KAction(parent) 00083 , d_ptr(&dd) 00084 { 00085 Q_D(KSelectAction); 00086 d->init(this); 00087 } 00088 00089 KSelectAction::~KSelectAction() 00090 { 00091 delete d_ptr; 00092 delete menu(); 00093 } 00094 00095 void KSelectActionPrivate::init(KSelectAction *q) 00096 { 00097 q_ptr = q; 00098 QObject::connect(q_ptr->selectableActionGroup(), SIGNAL(triggered(QAction*)), q_ptr, SLOT(actionTriggered(QAction*))); 00099 QObject::connect(q_ptr, SIGNAL(toggled(bool)), q_ptr, SLOT(slotToggled(bool))); 00100 q_ptr->setMenu(new KMenu()); 00101 q_ptr->setEnabled( false ); 00102 } 00103 00104 QActionGroup * KSelectAction::selectableActionGroup( ) const 00105 { 00106 Q_D(const KSelectAction); 00107 return d->m_actionGroup; 00108 } 00109 00110 QList<QAction*> KSelectAction::actions( ) const 00111 { 00112 return selectableActionGroup()->actions(); 00113 } 00114 00115 QAction* KSelectAction::currentAction() const 00116 { 00117 return selectableActionGroup()->checkedAction(); 00118 } 00119 00120 int KSelectAction::currentItem() const 00121 { 00122 return selectableActionGroup()->actions().indexOf(currentAction()); 00123 } 00124 00125 QString KSelectAction::currentText( ) const 00126 { 00127 if (QAction* a = currentAction()) 00128 return ::DropAmpersands(a->text()); 00129 00130 return QString(); 00131 } 00132 00133 bool KSelectAction::setCurrentAction(QAction* action) 00134 { 00135 //kDebug (129) << "KSelectAction::setCurrentAction(" << action << ")"; 00136 if (action) { 00137 if (actions().contains(action)) { 00138 if (action->isVisible() && action->isEnabled() && action->isCheckable()) { 00139 action->setChecked(true); 00140 if (isCheckable()) 00141 setChecked(true); 00142 return true; 00143 } else 00144 kWarning (129) << "Action does not have the correct properties to be current:" << action->text(); 00145 } else 00146 kWarning (129) << "Action does not belong to group:" << action->text(); 00147 return false; 00148 } 00149 00150 if (currentAction()) 00151 currentAction()->setChecked(false); 00152 00153 return false; 00154 } 00155 00156 bool KSelectAction::setCurrentItem( int index ) 00157 { 00158 //kDebug (129) << "KSelectAction::setCurrentIndex(" << index << ")"; 00159 return setCurrentAction(action(index)); 00160 } 00161 00162 QAction * KSelectAction::action( int index ) const 00163 { 00164 if (index >= 0 && index < selectableActionGroup()->actions().count()) 00165 return selectableActionGroup()->actions().at(index); 00166 00167 return 0L; 00168 } 00169 00170 QAction * KSelectAction::action( const QString & text, Qt::CaseSensitivity cs ) const 00171 { 00172 QString compare; 00173 if (cs == Qt::CaseSensitive) 00174 compare = text; 00175 else 00176 compare = text.toLower(); 00177 00178 foreach (QAction* action, selectableActionGroup()->actions()) { 00179 const QString text = ::DropAmpersands(action->text()); 00180 if (cs == Qt::CaseSensitive) { 00181 if (text == compare) { 00182 return action; 00183 } 00184 00185 } else if (cs == Qt::CaseInsensitive) { 00186 if (text.toLower() == compare) { 00187 return action; 00188 } 00189 } 00190 } 00191 00192 return 0L; 00193 } 00194 00195 bool KSelectAction::setCurrentAction( const QString & text, Qt::CaseSensitivity cs) 00196 { 00197 //kDebug (129) << "KSelectAction::setCurrentAction(" << text << ",cs=" << cs << ")"; 00198 return setCurrentAction(action(text, cs)); 00199 } 00200 00201 void KSelectAction::setComboWidth( int width ) 00202 { 00203 Q_D(KSelectAction); 00204 if ( width < 0 ) 00205 return; 00206 00207 d->m_comboWidth = width; 00208 00209 foreach (KComboBox* box, d->m_comboBoxes) 00210 box->setMaximumWidth(d->m_comboWidth); 00211 00212 emit changed(); 00213 } 00214 00215 void KSelectAction::setMaxComboViewCount( int n ) 00216 { 00217 Q_D(KSelectAction); 00218 d->m_maxComboViewCount = n; 00219 00220 foreach (KComboBox* box, d->m_comboBoxes) 00221 if ( d->m_maxComboViewCount != -1 ) 00222 box->setMaxVisibleItems(d->m_maxComboViewCount); 00223 else 00224 // hardcoded qt default 00225 box->setMaxVisibleItems(10); 00226 00227 emit changed(); 00228 } 00229 00230 void KSelectAction::addAction(QAction* action) 00231 { 00232 Q_D(KSelectAction); 00233 //kDebug (129) << "KSelectAction::addAction(" << action << ")"; 00234 00235 action->setActionGroup(selectableActionGroup()); 00236 00237 // Re-Enable when an action is added 00238 setEnabled(true); 00239 00240 // Keep in sync with createToolBarWidget() 00241 foreach (QToolButton* button, d->m_buttons) { 00242 button->setEnabled(true); 00243 button->addAction(action); 00244 } 00245 00246 foreach (KComboBox* comboBox, d->m_comboBoxes) { 00247 comboBox->setEnabled(true); 00248 comboBox->addAction(action); 00249 } 00250 00251 menu()->addAction(action); 00252 } 00253 00254 KAction* KSelectAction::addAction(const QString &text) 00255 { 00256 Q_D(KSelectAction); 00257 KAction* newAction = new KAction(parent()); 00258 newAction->setText(text); 00259 newAction->setCheckable( true ); 00260 newAction->setShortcutConfigurable(false); 00261 00262 if (!d->m_menuAccelsEnabled) { 00263 newAction->setText(text); 00264 newAction->setShortcut(QKeySequence()); 00265 } 00266 00267 addAction(newAction); 00268 return newAction; 00269 } 00270 00271 KAction* KSelectAction::addAction(const KIcon& icon, const QString& text) 00272 { 00273 KAction* newAction = addAction(text); 00274 newAction->setIcon(icon); 00275 return newAction; 00276 } 00277 00278 QAction* KSelectAction::removeAction(QAction* action) 00279 { 00280 Q_D(KSelectAction); 00281 //kDebug (129) << "KSelectAction::removeAction(" << action << ")"; 00282 //int index = selectableActionGroup()->actions().indexOf(action); 00283 //kDebug (129) << "\tindex=" << index; 00284 00285 // Removes the action from the group and sets its parent to null. 00286 d->m_actionGroup->removeAction(action); 00287 00288 // Disable when no action is in the group 00289 bool hasActions = selectableActionGroup()->actions().isEmpty(); 00290 setEnabled( !hasActions ); 00291 00292 foreach (QToolButton* button, d->m_buttons) { 00293 button->setEnabled( !hasActions ); 00294 button->removeAction(action); 00295 } 00296 00297 foreach (KComboBox* comboBox, d->m_comboBoxes) 00298 { 00299 comboBox->setEnabled( !hasActions ); 00300 comboBox->removeAction(action); 00301 } 00302 00303 menu()->removeAction(action); 00304 00305 00306 return action; 00307 } 00308 00309 void KSelectAction::actionTriggered(QAction* action) 00310 { 00311 // cache values so we don't need access to members in the action 00312 // after we've done an emit() 00313 const QString text = ::DropAmpersands(action->text()); 00314 const int index = selectableActionGroup()->actions().indexOf(action); 00315 //kDebug (129) << "KSelectAction::actionTriggered(" << action << ") text=" << text 00316 // << " index=" << index << " emitting triggered()" << endl; 00317 00318 if (isCheckable()) // if this is subsidiary of other KSelectAction-derived class 00319 trigger(); // then imitate usual QAction behaviour so that other submenus (and their items) become unchecked 00320 00321 emit triggered(action); 00322 emit triggered(index); 00323 emit triggered(text); 00324 } 00325 00326 QStringList KSelectAction::items() const 00327 { 00328 Q_D(const KSelectAction); 00329 QStringList ret; 00330 00331 foreach (QAction* action, d->m_actionGroup->actions()) 00332 ret << ::DropAmpersands(action->text()); 00333 00334 return ret; 00335 } 00336 00337 void KSelectAction::changeItem( int index, const QString& text ) 00338 { 00339 Q_D(KSelectAction); 00340 if ( index < 0 || index >= actions().count() ) 00341 { 00342 kWarning() << "KSelectAction::changeItem Index out of scope"; 00343 return; 00344 } 00345 00346 actions()[index]->setText( d->makeMenuText( text ) ); 00347 } 00348 00349 void KSelectAction::setItems( const QStringList &lst ) 00350 { 00351 Q_D(KSelectAction); 00352 //kDebug (129) << "KSelectAction::setItems(" << lst << ")"; 00353 00354 clear(); 00355 00356 foreach (const QString& string, lst) { 00357 if ( !string.isEmpty() ) { 00358 addAction(string); 00359 } else { 00360 QAction* action = new QAction(this); 00361 action->setSeparator(true); 00362 addAction(action); 00363 } 00364 } 00365 00366 // Disable if empty and not editable 00367 setEnabled( lst.count() > 0 || d->m_edit ); 00368 } 00369 00370 int KSelectAction::comboWidth() const 00371 { 00372 Q_D(const KSelectAction); 00373 return d->m_comboWidth; 00374 } 00375 00376 void KSelectAction::clear() 00377 { 00378 Q_D(KSelectAction); 00379 //kDebug (129) << "KSelectAction::clear()"; 00380 00381 // we need to delete the actions later since we may get a call to clear() 00382 // from a method called due to a triggered(...) signal 00383 const QList<QAction*> actions = d->m_actionGroup->actions(); 00384 for (int i = 0; i < actions.count(); ++i) 00385 { 00386 // deleteLater() only removes us from the actions() list (among 00387 // other things) on the next entry into the event loop. Until then, 00388 // e.g. action() and setCurrentItem() will be working on items 00389 // that are supposed to have been deleted. So detach the action to 00390 // prevent this from happening. 00391 removeAction(actions[i]); 00392 00393 actions[i]->deleteLater(); 00394 } 00395 } 00396 00397 void KSelectAction::removeAllActions( ) 00398 { 00399 Q_D(KSelectAction); 00400 while (d->m_actionGroup->actions().count()) 00401 removeAction(d->m_actionGroup->actions().first()); 00402 } 00403 00404 void KSelectAction::setEditable( bool edit ) 00405 { 00406 Q_D(KSelectAction); 00407 d->m_edit = edit; 00408 00409 foreach (KComboBox* comboBox, d->m_comboBoxes) 00410 comboBox->setEditable(edit); 00411 00412 emit changed(); 00413 } 00414 00415 bool KSelectAction::isEditable() const 00416 { 00417 Q_D(const KSelectAction); 00418 return d->m_edit; 00419 } 00420 00421 void KSelectAction::slotToggled(bool checked) 00422 { 00423 //if (checked && selectableActionGroup()->checkedAction()) 00424 if (!checked && currentAction()) // other's submenu item has been selected 00425 currentAction()->setChecked(false); 00426 } 00427 00428 KSelectAction::ToolBarMode KSelectAction::toolBarMode() const 00429 { 00430 Q_D(const KSelectAction); 00431 return d->m_toolBarMode; 00432 } 00433 00434 void KSelectAction::setToolBarMode( ToolBarMode mode ) 00435 { 00436 Q_D(KSelectAction); 00437 d->m_toolBarMode = mode; 00438 } 00439 00440 QToolButton::ToolButtonPopupMode KSelectAction::toolButtonPopupMode( ) const 00441 { 00442 Q_D(const KSelectAction); 00443 return d->m_toolButtonPopupMode; 00444 } 00445 00446 void KSelectAction::setToolButtonPopupMode( QToolButton::ToolButtonPopupMode mode ) 00447 { 00448 Q_D(KSelectAction); 00449 d->m_toolButtonPopupMode = mode; 00450 } 00451 00452 void KSelectActionPrivate::_k_comboBoxDeleted(QObject* object) 00453 { 00454 foreach (KComboBox* comboBox, m_comboBoxes) 00455 if (object == comboBox) { 00456 m_comboBoxes.removeAll(static_cast<KComboBox*>(object)); 00457 break; 00458 } 00459 } 00460 00461 void KSelectActionPrivate::_k_comboBoxCurrentIndexChanged(int index) 00462 { 00463 Q_Q(KSelectAction); 00464 //kDebug (129) << "KSelectActionPrivate::_k_comboBoxCurrentIndexChanged(" << index << ")"; 00465 00466 KComboBox *triggeringCombo = qobject_cast <KComboBox *> (q->sender ()); 00467 00468 QAction *a = q->action(index); 00469 //kDebug (129) << "\ta=" << a; 00470 if (a) { 00471 //kDebug (129) << "\t\tsetting as current action"; 00472 a->trigger(); 00473 00474 } else if (q->isEditable () && 00475 triggeringCombo && triggeringCombo->count () > 0 && 00476 index == triggeringCombo->count () - 1) { 00477 00478 // User must have added a new item by typing and pressing enter. 00479 const QString newItemText = triggeringCombo->currentText (); 00480 //kDebug (129) << "\t\tuser typed new item '" << newItemText << "'"; 00481 00482 // Only 1 combobox contains this and it's not a proper action. 00483 bool blocked = triggeringCombo->blockSignals (true); 00484 triggeringCombo->removeItem (index); 00485 triggeringCombo->blockSignals (blocked); 00486 00487 KAction *newAction = q->addAction (newItemText); 00488 00489 newAction->trigger(); 00490 } else { 00491 if (q->selectableActionGroup()->checkedAction()) 00492 q->selectableActionGroup()->checkedAction()->setChecked(false); 00493 } 00494 } 00495 00496 // TODO: DropAmpersands() certainly makes sure this doesn't work. But I don't 00497 // think it did anyway esp. in the presence KCheckAccelerator - Clarence. 00498 void KSelectAction::setMenuAccelsEnabled( bool b ) 00499 { 00500 Q_D(KSelectAction); 00501 d->m_menuAccelsEnabled = b; 00502 } 00503 00504 bool KSelectAction::menuAccelsEnabled() const 00505 { 00506 Q_D(const KSelectAction); 00507 return d->m_menuAccelsEnabled; 00508 } 00509 00510 QWidget * KSelectAction::createWidget( QWidget * parent ) 00511 { 00512 Q_D(KSelectAction); 00513 QMenu *menu = qobject_cast<QMenu *>(parent); 00514 if (menu) // If used in a menu want to return 0 and use only the text, not a widget 00515 return 0; 00516 ToolBarMode mode = toolBarMode(); 00517 QToolBar *toolBar = qobject_cast<QToolBar *>(parent); 00518 if (!toolBar && mode != ComboBoxMode) { // we can return a combobox just fine. 00519 return 0; 00520 } 00521 switch (mode) { 00522 case MenuMode: { 00523 QToolButton* button = new QToolButton(toolBar); 00524 button->setToolTip(toolTip()); 00525 button->setWhatsThis(whatsThis()); 00526 button->setStatusTip(statusTip()); 00527 button->setAutoRaise(true); 00528 button->setFocusPolicy(Qt::NoFocus); 00529 button->setIconSize(toolBar->iconSize()); 00530 button->setToolButtonStyle(toolBar->toolButtonStyle()); 00531 QObject::connect(toolBar, SIGNAL(iconSizeChanged(const QSize&)), 00532 button, SLOT(setIconSize(const QSize&))); 00533 QObject::connect(toolBar, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)), 00534 button, SLOT(setToolButtonStyle(Qt::ToolButtonStyle))); 00535 button->setDefaultAction(this); 00536 QObject::connect(button, SIGNAL(triggered(QAction*)), toolBar, SIGNAL(actionTriggered(QAction*))); 00537 00538 button->setPopupMode(toolButtonPopupMode()); 00539 00540 button->addActions(selectableActionGroup()->actions()); 00541 00542 d->m_buttons.append(button); 00543 return button; 00544 } 00545 00546 case ComboBoxMode: { 00547 KComboBox* comboBox = new KComboBox(parent); 00548 comboBox->installEventFilter (this); 00549 00550 if ( d->m_maxComboViewCount != -1 ) 00551 comboBox->setMaxVisibleItems( d->m_maxComboViewCount ); 00552 00553 if ( d->m_comboWidth > 0 ) 00554 comboBox->setMaximumWidth( d->m_comboWidth ); 00555 00556 comboBox->setEditable(isEditable()); 00557 comboBox->setToolTip(toolTip()); 00558 comboBox->setWhatsThis(whatsThis()); 00559 comboBox->setStatusTip(statusTip()); 00560 00561 foreach (QAction* action, selectableActionGroup()->actions()) 00562 comboBox->addAction(action); 00563 00564 if (selectableActionGroup()->actions().isEmpty()) 00565 comboBox->setEnabled(false); 00566 00567 connect(comboBox, SIGNAL(destroyed(QObject*)), SLOT(_k_comboBoxDeleted(QObject*))); 00568 connect(comboBox, SIGNAL(currentIndexChanged(int)), SLOT(_k_comboBoxCurrentIndexChanged(int))); 00569 d->m_comboBoxes.append(comboBox); 00570 00571 return comboBox; 00572 } 00573 } 00574 00575 return 0L; 00576 } 00577 00578 void KSelectAction::deleteWidget(QWidget *widget) 00579 { 00580 Q_D(KSelectAction); 00581 if (QToolButton *toolButton = qobject_cast<QToolButton *>(widget)) 00582 d->m_buttons.removeAll(toolButton); 00583 else if (KComboBox *comboBox = qobject_cast<KComboBox *>(widget)) 00584 d->m_comboBoxes.removeAll(comboBox); 00585 KAction::deleteWidget(widget); 00586 } 00587 00588 bool KSelectAction::event(QEvent *event) 00589 { 00590 Q_D(KSelectAction); 00591 if (event->type() == QEvent::ActionChanged) { 00592 Q_FOREACH(KComboBox* comboBox, d->m_comboBoxes) { 00593 comboBox->setToolTip(toolTip()); 00594 comboBox->setWhatsThis(whatsThis()); 00595 comboBox->setStatusTip(statusTip()); 00596 } 00597 Q_FOREACH(QToolButton* toolButton, d->m_buttons) { 00598 toolButton->setToolTip(toolTip()); 00599 toolButton->setWhatsThis(whatsThis()); 00600 toolButton->setStatusTip(statusTip()); 00601 } 00602 } 00603 return KAction::event(event); 00604 } 00605 00606 // KSelectAction::eventFilter() is called before action->setChecked() 00607 // invokes the signal to update QActionGroup so KSelectAction::currentItem() 00608 // returns an old value. There are 3 possibilities, where n actions will 00609 // report QAction::isChecked() where n is: 00610 // 00611 // 0: the checked action was unchecked 00612 // 1: the checked action did not change 00613 // 2: another action was checked but QActionGroup has not been invoked yet 00614 // to uncheck the one that was checked before 00615 // 00616 // TODO: we might want to cache this since QEvent::ActionChanged is fired 00617 // often. 00618 static int TrueCurrentItem (KSelectAction *sa) 00619 { 00620 QAction *curAction = sa->currentAction (); 00621 //kDebug (129) << "\tTrueCurrentItem(" << sa << ") curAction=" << curAction; 00622 00623 foreach (QAction *action, sa->actions ()) 00624 { 00625 if (action->isChecked ()) 00626 { 00627 //kDebug (129) << "\t\taction " << action << " (text=" << action->text () << ") isChecked"; 00628 00629 // 2 actions checked case? 00630 if (action != curAction) 00631 { 00632 //kDebug (129) << "\t\t\tmust be newly selected one"; 00633 return sa->actions ().indexOf (action); 00634 } 00635 } 00636 } 00637 00638 //kDebug (129) << "\t\tcurrent action still selected? " << (curAction && curAction->isChecked ()); 00639 // 1 or 0 actions checked case (in that order)? 00640 return (curAction && curAction->isChecked ()) ? sa->actions ().indexOf (curAction) : -1; 00641 } 00642 00643 // We store the QAction* as the userData of each combobox item 00644 Q_DECLARE_METATYPE(QAction*) 00645 00646 bool KSelectAction::eventFilter (QObject *watched, QEvent *event) 00647 { 00648 KComboBox *comboBox = qobject_cast <KComboBox *> (watched); 00649 if (!comboBox) 00650 return false/*propagate event*/; 00651 00652 00653 // If focus is lost, replace any edited text with the currently selected 00654 // item. 00655 if (event->type () == QEvent::FocusOut) { 00656 QFocusEvent * const e = static_cast <QFocusEvent *> (event); 00657 //kDebug (129) << "KSelectAction::eventFilter(FocusOut)" 00658 // << " comboBox: ptr=" << comboBox 00659 // << " reason=" << e->reason () 00660 // << endl; 00661 00662 if (e->reason () != Qt::ActiveWindowFocusReason/*switch window*/ && 00663 e->reason () != Qt::PopupFocusReason/*menu*/ && 00664 e->reason () != Qt::OtherFocusReason/*inconsistently reproduceable actions...*/) { 00665 00666 //kDebug (129) << "\tkilling text"; 00667 comboBox->setEditText (comboBox->itemText (comboBox->currentIndex ())); 00668 } 00669 00670 return false/*propagate event*/; 00671 } 00672 00673 bool blocked = comboBox->blockSignals (true); 00674 00675 if (event->type () == QEvent::ActionAdded) 00676 { 00677 QActionEvent * const e = static_cast <QActionEvent *> (event); 00678 00679 const int index = e->before () ? 00680 comboBox->findData (QVariant::fromValue (e->before ())) : 00681 comboBox->count (); 00682 const int newItem = ::TrueCurrentItem (this); 00683 //kDebug (129) << "KSelectAction::eventFilter(ActionAdded)" 00684 // << " comboBox: ptr=" << comboBox 00685 // << " currentItem=" << comboBox->currentIndex () 00686 // << " add index=" << index 00687 // << " action new: e->before=" << e->before () 00688 // << " ptr=" << e->action () 00689 // << " icon=" << e->action ()->icon () 00690 // << " text=" << e->action ()->text () 00691 // << " currentItem=" << newItem 00692 // << endl; 00693 comboBox->insertItem (index, 00694 e->action()->icon(), 00695 ::DropAmpersands (e->action()->text()), 00696 QVariant::fromValue (e->action ())); 00697 if (QStandardItemModel *model = qobject_cast<QStandardItemModel *>(comboBox->model())) { 00698 QStandardItem *item = model->item(index); 00699 item->setEnabled(e->action()->isEnabled()); 00700 } 00701 00702 // Inserting an item into a combobox can change the current item so 00703 // make sure the item corresponding to the checked action is selected. 00704 comboBox->setCurrentIndex (newItem); 00705 } 00706 else if (event->type () == QEvent::ActionChanged) 00707 { 00708 QActionEvent * const e = static_cast <QActionEvent *> (event); 00709 00710 const int index = comboBox->findData (QVariant::fromValue (e->action ())); 00711 const int newItem = ::TrueCurrentItem (this); 00712 //kDebug (129) << "KSelectAction::eventFilter(ActionChanged)" 00713 // << " comboBox: ptr=" << comboBox 00714 // << " currentItem=" << comboBox->currentIndex () 00715 // << " changed action's index=" << index 00716 // << " action new: ptr=" << e->action () 00717 // << " icon=" << e->action ()->icon () 00718 // << " text=" << e->action ()->text () 00719 // << " currentItem=" << newItem 00720 // << endl; 00721 comboBox->setItemIcon (index, e->action ()->icon ()); 00722 comboBox->setItemText (index, ::DropAmpersands (e->action ()->text ())); 00723 if (QStandardItemModel *model = qobject_cast<QStandardItemModel *>(comboBox->model())) { 00724 QStandardItem *item = model->item(index); 00725 item->setEnabled(e->action()->isEnabled()); 00726 } 00727 00728 // The checked action may have become unchecked so 00729 // make sure the item corresponding to the checked action is selected. 00730 comboBox->setCurrentIndex (newItem); 00731 } 00732 else if (event->type () == QEvent::ActionRemoved) 00733 { 00734 QActionEvent * const e = static_cast <QActionEvent *> (event); 00735 00736 const int index = comboBox->findData (QVariant::fromValue (e->action ())); 00737 const int newItem = ::TrueCurrentItem (this); 00738 //kDebug (129) << "KSelectAction::eventFilter(ActionRemoved)" 00739 // << " comboBox: ptr=" << comboBox 00740 // << " currentItem=" << comboBox->currentIndex () 00741 // << " delete action index=" << index 00742 // << " new: currentItem=" << newItem 00743 // << endl; 00744 comboBox->removeItem (index); 00745 00746 // Removing an item from a combobox can change the current item so 00747 // make sure the item corresponding to the checked action is selected. 00748 comboBox->setCurrentIndex (newItem); 00749 } 00750 00751 comboBox->blockSignals (blocked); 00752 00753 return false/*propagate event*/; 00754 } 00755 00756 // END 00757 00758 /* vim: et sw=2 ts=2 00759 */ 00760 00761 #include "kselectaction.moc"
KDE 4.6 API Reference