kdeui Library API Documentation

kaction.cpp

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 00011 This library is free software; you can redistribute it and/or 00012 modify it under the terms of the GNU Library General Public 00013 License version 2 as published by the Free Software Foundation. 00014 00015 This library is distributed in the hope that it will be useful, 00016 but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 Library General Public License for more details. 00019 00020 You should have received a copy of the GNU Library General Public License 00021 along with this library; see the file COPYING.LIB. If not, write to 00022 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00023 Boston, MA 02111-1307, USA. 00024 */ 00025 00026 #include "kaction.h" 00027 00028 #include <assert.h> 00029 00030 #include <qtooltip.h> 00031 #include <qwhatsthis.h> 00032 00033 #include <kaccel.h> 00034 #include <kaccelbase.h> 00035 #include <kapplication.h> 00036 #include <kdebug.h> 00037 #include <kguiitem.h> 00038 #include <kmainwindow.h> 00039 #include <kmenubar.h> 00040 #include <kpopupmenu.h> 00041 #include <ktoolbar.h> 00042 #include <ktoolbarbutton.h> 00043 00065 int KAction::getToolButtonID() 00066 { 00067 static int toolbutton_no = -2; 00068 return toolbutton_no--; 00069 } 00070 00071 //--------------------------------------------------------------------- 00072 // KAction::KActionPrivate 00073 //--------------------------------------------------------------------- 00074 00075 class KAction::KActionPrivate : public KGuiItem 00076 { 00077 public: 00078 KActionPrivate() : KGuiItem() 00079 { 00080 m_kaccel = 0; 00081 m_configurable = true; 00082 } 00083 00084 KAccel *m_kaccel; 00085 QValueList<KAccel*> m_kaccelList; 00086 00087 QString m_groupText; 00088 QString m_group; 00089 00090 KShortcut m_cut; 00091 KShortcut m_cutDefault; 00092 00093 bool m_configurable; 00094 00095 struct Container 00096 { 00097 Container() { m_container = 0; m_representative = 0; m_id = 0; } 00098 Container( const Container& s ) { m_container = s.m_container; 00099 m_id = s.m_id; m_representative = s.m_representative; } 00100 QWidget* m_container; 00101 int m_id; 00102 QWidget* m_representative; 00103 }; 00104 00105 QValueList<Container> m_containers; 00106 }; 00107 00108 //--------------------------------------------------------------------- 00109 // KAction 00110 //--------------------------------------------------------------------- 00111 00112 KAction::KAction( const QString& text, const KShortcut& cut, 00113 const QObject* receiver, const char* slot, 00114 KActionCollection* parent, const char* name ) 00115 : QObject( parent, name ) 00116 { 00117 initPrivate( text, cut, receiver, slot ); 00118 } 00119 00120 KAction::KAction( const QString& text, const QString& sIconName, const KShortcut& cut, 00121 const QObject* receiver, const char* slot, 00122 KActionCollection* parent, const char* name ) 00123 : QObject( parent, name ) 00124 { 00125 initPrivate( text, cut, receiver, slot ); 00126 d->setIconName( sIconName ); 00127 } 00128 00129 KAction::KAction( const QString& text, const QIconSet& pix, const KShortcut& cut, 00130 const QObject* receiver, const char* slot, 00131 KActionCollection* parent, const char* name ) 00132 : QObject( parent, name ) 00133 { 00134 initPrivate( text, cut, receiver, slot ); 00135 d->setIconSet( pix ); 00136 } 00137 00138 KAction::KAction( const KGuiItem& item, const KShortcut& cut, 00139 const QObject* receiver, const char* slot, 00140 KActionCollection* parent, const char* name ) 00141 : QObject( parent, name ) 00142 { 00143 initPrivate( item.text(), cut, receiver, slot ); 00144 if( item.hasIconSet() ) 00145 setIcon( item.iconName() ); 00146 setToolTip( item.toolTip() ); 00147 setWhatsThis( item.whatsThis() ); 00148 } 00149 00150 // KDE 4: remove 00151 KAction::KAction( const QString& text, const KShortcut& cut, 00152 QObject* parent, const char* name ) 00153 : QObject( parent, name ) 00154 { 00155 initPrivate( text, cut, 0, 0 ); 00156 } 00157 00158 KAction::KAction( const QString& text, const KShortcut& cut, 00159 const QObject* receiver, 00160 const char* slot, QObject* parent, const char* name ) 00161 : QObject( parent, name ) 00162 { 00163 initPrivate( text, cut, receiver, slot ); 00164 } 00165 00166 KAction::KAction( const QString& text, const QIconSet& pix, 00167 const KShortcut& cut, 00168 QObject* parent, const char* name ) 00169 : QObject( parent, name ) 00170 { 00171 initPrivate( text, cut, 0, 0 ); 00172 setIconSet( pix ); 00173 } 00174 00175 KAction::KAction( const QString& text, const QString& pix, 00176 const KShortcut& cut, 00177 QObject* parent, const char* name ) 00178 : QObject( parent, name ) 00179 { 00180 initPrivate( text, cut, 0, 0 ); 00181 d->setIconName( pix ); 00182 } 00183 00184 KAction::KAction( const QString& text, const QIconSet& pix, 00185 const KShortcut& cut, 00186 const QObject* receiver, const char* slot, QObject* parent, 00187 const char* name ) 00188 : QObject( parent, name ) 00189 { 00190 initPrivate( text, cut, receiver, slot ); 00191 setIconSet( pix ); 00192 } 00193 00194 KAction::KAction( const QString& text, const QString& pix, 00195 const KShortcut& cut, 00196 const QObject* receiver, const char* slot, QObject* parent, 00197 const char* name ) 00198 : QObject( parent, name ) 00199 { 00200 initPrivate( text, cut, receiver, slot ); 00201 d->setIconName(pix); 00202 } 00203 00204 KAction::KAction( QObject* parent, const char* name ) 00205 : QObject( parent, name ) 00206 { 00207 initPrivate( QString::null, KShortcut(), 0, 0 ); 00208 } 00209 // KDE 4: remove end 00210 00211 KAction::~KAction() 00212 { 00213 kdDebug(129) << "KAction::~KAction( this = \"" << name() << "\" )" << endl; // -- ellis 00214 #ifndef KDE_NO_COMPAT 00215 if (d->m_kaccel) 00216 unplugAccel(); 00217 #endif 00218 00219 // If actionCollection hasn't already been destructed, 00220 if ( m_parentCollection ) { 00221 m_parentCollection->take( this ); 00222 for( uint i = 0; i < d->m_kaccelList.count(); i++ ) 00223 d->m_kaccelList[i]->remove( name() ); 00224 } 00225 00226 // Do not call unplugAll from here, as tempting as it sounds. 00227 // KAction is designed around the idea that you need to plug 00228 // _and_ to unplug it "manually". Unplugging leads to an important 00229 // slowdown when e.g. closing the window, in which case we simply 00230 // want to destroy everything asap, not to remove actions one by one 00231 // from the GUI. 00232 00233 delete d; d = 0; 00234 } 00235 00236 void KAction::initPrivate( const QString& text, const KShortcut& cut, 00237 const QObject* receiver, const char* slot ) 00238 { 00239 d = new KActionPrivate; 00240 00241 d->m_cutDefault = cut; 00242 00243 m_parentCollection = dynamic_cast<KActionCollection *>( parent() ); 00244 kdDebug(129) << "KAction::initPrivate(): this = " << this << " name = \"" << name() << "\" cut = " << cut.toStringInternal() << " m_parentCollection = " << m_parentCollection << endl; 00245 if ( m_parentCollection ) 00246 m_parentCollection->insert( this ); 00247 00248 if ( receiver && slot ) 00249 connect( this, SIGNAL( activated() ), receiver, slot ); 00250 00251 if( !cut.isNull() && qstrcmp( name(), "unnamed" ) == 0 ) 00252 kdWarning(129) << "KAction::initPrivate(): trying to assign a shortcut (" << cut.toStringInternal() << ") to an unnamed action." << endl; 00253 d->setText( text ); 00254 initShortcut( cut ); 00255 } 00256 00257 bool KAction::isPlugged() const 00258 { 00259 return (containerCount() > 0) || d->m_kaccel; 00260 } 00261 00262 bool KAction::isPlugged( const QWidget *container ) const 00263 { 00264 return findContainer( container ) > -1; 00265 } 00266 00267 bool KAction::isPlugged( const QWidget *container, int id ) const 00268 { 00269 int i = findContainer( container ); 00270 return ( i > -1 && itemId( i ) == id ); 00271 } 00272 00273 bool KAction::isPlugged( const QWidget *container, const QWidget *_representative ) const 00274 { 00275 int i = findContainer( container ); 00276 return ( i > -1 && representative( i ) == _representative ); 00277 } 00278 00279 00280 /* 00281 Three actionCollection conditions: 00282 1) Scope is known on creation and KAccel object is created (e.g. KMainWindow) 00283 2) Scope is unknown and no KAccel object is available (e.g. KXMLGUIClient) 00284 a) addClient() will be called on object 00285 b) we just want to add the actions to another KXMLGUIClient object 00286 00287 The question is how to do we incorporate #2b into the XMLGUI framework? 00288 00289 00290 We have a KCommandHistory object with undo and redo actions in a passed actionCollection 00291 We have a KoDoc object which holds a KCommandHistory object and the actionCollection 00292 We have two KoView objects which both point to the same KoDoc object 00293 Undo and Redo should be available in both KoView objects, and 00294 calling the undo->setEnabled() should affect both KoViews 00295 00296 When addClient is called, it needs to be able to find the undo and redo actions 00297 When it calls plug() on them, they need to be inserted into the KAccel object of the appropriate KoView 00298 00299 In this case, the actionCollection belongs to KoDoc and we need to let it know that its shortcuts 00300 have the same scope as the KoView actionCollection 00301 00302 KXMLGUIClient::addSubActionCollection 00303 00304 Document: 00305 create document actions 00306 00307 View 00308 create view actions 00309 add document actionCollection as sub-collection 00310 00311 A parentCollection is created 00312 Scenario 1: parentCollection has a focus widget set (e.g. via KMainWindow) 00313 A KAccel object is created in the parentCollection 00314 A KAction is created with parent=parentCollection 00315 The shortcut is inserted into this actionCollection 00316 Scenario 1a: xml isn't used 00317 done 00318 Scenario 1b: KXMLGUIBuilder::addClient() called 00319 setWidget is called -- ignore 00320 shortcuts are set 00321 Scenario 2: parentCollection has no focus widget (e.g., KParts) 00322 A KAction is created with parent=parentCollection 00323 Scenario 2a: xml isn't used 00324 no shortcuts 00325 Scenario 2b: KXMLGUIBuilder::addClient() called 00326 setWidget is called 00327 shortcuts are inserted into current KAccel 00328 shortcuts are set in all other KAccels, if the action is present in the other KAccels 00329 */ 00330 00331 /* 00332 shortcut may be set: 00333 - on construction 00334 - on plug 00335 - on reading XML 00336 - on plugAccel (deprecated) 00337 00338 On Construction: [via initShortcut()] 00339 insert into KAccel of m_parentCollection, 00340 if kaccel() && isAutoConnectShortcuts() exists 00341 00342 On Plug: [via plug() -> plugShortcut()] 00343 insert into KAccel of m_parentCollection, if exists and not already inserted into 00344 00345 On Read XML: [via setShortcut()] 00346 set in all current KAccels 00347 insert into KAccel of m_parentCollection, if exists and not already inserted into 00348 */ 00349 00350 KAccel* KAction::kaccelCurrent() 00351 { 00352 if( m_parentCollection && m_parentCollection->builderKAccel() ) 00353 return m_parentCollection->builderKAccel(); 00354 else if( m_parentCollection && m_parentCollection->kaccel() ) 00355 return m_parentCollection->kaccel(); 00356 else 00357 return 0L; 00358 } 00359 00360 // Only to be called from initPrivate() 00361 bool KAction::initShortcut( const KShortcut& cut ) 00362 { 00363 d->m_cut = cut; 00364 00365 // Only insert action into KAccel if it has a valid name, 00366 if( qstrcmp( name(), "unnamed" ) != 0 && 00367 m_parentCollection && 00368 m_parentCollection->isAutoConnectShortcuts() && 00369 m_parentCollection->kaccel() ) 00370 { 00371 insertKAccel( m_parentCollection->kaccel() ); 00372 return true; 00373 } 00374 return false; 00375 } 00376 00377 // Only to be called from plug() 00378 void KAction::plugShortcut() 00379 { 00380 KAccel* kaccel = kaccelCurrent(); 00381 00382 //kdDebug(129) << "KAction::plugShortcut(): this = " << this << " kaccel() = " << (m_parentCollection ? m_parentCollection->kaccel() : 0) << endl; 00383 if( kaccel && qstrcmp( name(), "unnamed" ) != 0 ) { 00384 // Check if already plugged into current KAccel object 00385 for( uint i = 0; i < d->m_kaccelList.count(); i++ ) { 00386 if( d->m_kaccelList[i] == kaccel ) 00387 return; 00388 } 00389 00390 insertKAccel( kaccel ); 00391 } 00392 } 00393 00394 bool KAction::setShortcut( const KShortcut& cut ) 00395 { 00396 bool bChanged = (d->m_cut != cut); 00397 d->m_cut = cut; 00398 00399 KAccel* kaccel = kaccelCurrent(); 00400 bool bInsertRequired = true; 00401 // Apply new shortcut to all existing KAccel objects 00402 for( uint i = 0; i < d->m_kaccelList.count(); i++ ) { 00403 // Check whether shortcut has already been plugged into 00404 // the current kaccel object. 00405 if( d->m_kaccelList[i] == kaccel ) 00406 bInsertRequired = false; 00407 if( bChanged ) 00408 updateKAccelShortcut( d->m_kaccelList[i] ); 00409 } 00410 00411 // Only insert action into KAccel if it has a valid name, 00412 if( kaccel && bInsertRequired && qstrcmp( name(), "unnamed" ) ) 00413 insertKAccel( kaccel ); 00414 00415 if( bChanged ) { 00416 // KDE 4: remove 00417 if ( d->m_kaccel ) 00418 d->m_kaccel->setShortcut( name(), cut ); 00419 // KDE 4: remove end 00420 int len = containerCount(); 00421 for( int i = 0; i < len; ++i ) 00422 updateShortcut( i ); 00423 } 00424 return true; 00425 } 00426 00427 bool KAction::updateKAccelShortcut( KAccel* kaccel ) 00428 { 00429 // Check if action is permitted 00430 if (kapp && !kapp->authorizeKAction(name())) 00431 return false; 00432 00433 bool b = true; 00434 00435 if ( !kaccel->actions().actionPtr( name() ) ) { 00436 if(!d->m_cut.isNull() ) { 00437 kdDebug(129) << "Inserting " << name() << ", " << d->text() << ", " << d->plainText() << endl; 00438 b = kaccel->insert( name(), d->plainText(), QString::null, 00439 d->m_cut, 00440 this, SLOT(slotActivated()), 00441 isShortcutConfigurable(), isEnabled() ); 00442 } 00443 } 00444 else 00445 b = kaccel->setShortcut( name(), d->m_cut ); 00446 00447 return b; 00448 } 00449 00450 void KAction::insertKAccel( KAccel* kaccel ) 00451 { 00452 //kdDebug(129) << "KAction::insertKAccel( " << kaccel << " ): this = " << this << endl; 00453 if ( !kaccel->actions().actionPtr( name() ) ) { 00454 if( updateKAccelShortcut( kaccel ) ) { 00455 d->m_kaccelList.append( kaccel ); 00456 connect( kaccel, SIGNAL(destroyed()), this, SLOT(slotDestroyed()) ); 00457 } 00458 } 00459 else 00460 kdWarning(129) << "KAction::insertKAccel( kaccel = " << kaccel << " ): KAccel object already contains an action name \"" << name() << "\"" << endl; // -- ellis 00461 } 00462 00463 void KAction::removeKAccel( KAccel* kaccel ) 00464 { 00465 //kdDebug(129) << "KAction::removeKAccel( " << i << " ): this = " << this << endl; 00466 for( uint i = 0; i < d->m_kaccelList.count(); i++ ) { 00467 if( d->m_kaccelList[i] == kaccel ) { 00468 kaccel->remove( name() ); 00469 d->m_kaccelList.remove( d->m_kaccelList.at( i ) ); 00470 disconnect( kaccel, SIGNAL(destroyed()), this, SLOT(slotDestroyed()) ); 00471 break; 00472 } 00473 } 00474 } 00475 00476 // KDE 4: remove 00477 void KAction::setAccel( int keyQt ) 00478 { 00479 setShortcut( KShortcut(keyQt) ); 00480 } 00481 // KDE 4: remove end 00482 00483 void KAction::updateShortcut( int i ) 00484 { 00485 int id = itemId( i ); 00486 00487 QWidget* w = container( i ); 00488 if ( w->inherits( "QPopupMenu" ) ) { 00489 QPopupMenu* menu = static_cast<QPopupMenu*>(w); 00490 updateShortcut( menu, id ); 00491 } 00492 else if ( w->inherits( "QMenuBar" ) ) 00493 static_cast<QMenuBar*>(w)->setAccel( d->m_cut.keyCodeQt(), id ); 00494 } 00495 00496 void KAction::updateShortcut( QPopupMenu* menu, int id ) 00497 { 00498 //kdDebug(129) << "KAction::updateShortcut(): this = " << this << " d->m_kaccelList.count() = " << d->m_kaccelList.count() << endl; 00499 // If the action has a KAccel object, 00500 // show the string representation of its shortcut. 00501 if ( d->m_kaccel || d->m_kaccelList.count() ) { 00502 QString s = menu->text( id ); 00503 int i = s.find( '\t' ); 00504 if ( i >= 0 ) 00505 s.replace( i+1, s.length()-i, d->m_cut.seq(0).toString() ); 00506 else 00507 s += "\t" + d->m_cut.seq(0).toString(); 00508 00509 menu->changeItem( id, s ); 00510 } 00511 // Otherwise insert the shortcut itself into the popup menu. 00512 else { 00513 // This is a fall-hack in case the KAction is missing a proper parent collection. 00514 // It should be removed eventually. --ellis 00515 menu->setAccel( d->m_cut.keyCodeQt(), id ); 00516 kdDebug(129) << "KAction::updateShortcut(): name = \"" << name() << "\", cut = " << d->m_cut.toStringInternal() << "; No KAccel, probably missing a parent collection." << endl; 00517 } 00518 } 00519 00520 const KShortcut& KAction::shortcut() const 00521 { 00522 return d->m_cut; 00523 } 00524 00525 const KShortcut& KAction::shortcutDefault() const 00526 { 00527 return d->m_cutDefault; 00528 } 00529 00530 QString KAction::shortcutText() const 00531 { 00532 return d->m_cut.toStringInternal(); 00533 } 00534 00535 void KAction::setShortcutText( const QString& s ) 00536 { 00537 setShortcut( KShortcut(s) ); 00538 } 00539 00540 int KAction::accel() const 00541 { 00542 return d->m_cut.keyCodeQt(); 00543 } 00544 00545 void KAction::setGroup( const QString& grp ) 00546 { 00547 d->m_group = grp; 00548 00549 int len = containerCount(); 00550 for( int i = 0; i < len; ++i ) 00551 updateGroup( i ); 00552 } 00553 00554 void KAction::updateGroup( int ) 00555 { 00556 // DO SOMETHING 00557 } 00558 00559 QString KAction::group() const 00560 { 00561 return d->m_group; 00562 } 00563 00564 bool KAction::isEnabled() const 00565 { 00566 return d->isEnabled(); 00567 } 00568 00569 bool KAction::isShortcutConfigurable() const 00570 { 00571 return d->m_configurable; 00572 } 00573 00574 void KAction::setToolTip( const QString& tt ) 00575 { 00576 d->setToolTip( tt ); 00577 00578 int len = containerCount(); 00579 for( int i = 0; i < len; ++i ) 00580 updateToolTip( i ); 00581 } 00582 00583 void KAction::updateToolTip( int i ) 00584 { 00585 QWidget *w = container( i ); 00586 00587 if ( w->inherits( "KToolBar" ) ) 00588 QToolTip::add( static_cast<KToolBar*>(w)->getWidget( itemId( i ) ), d->toolTip() ); 00589 } 00590 00591 QString KAction::toolTip() const 00592 { 00593 return d->toolTip(); 00594 } 00595 00596 int KAction::plug( QWidget *w, int index ) 00597 { 00598 //kdDebug(129) << "KAction::plug( " << w << ", " << index << " )" << endl; 00599 if (w == 0) { 00600 kdWarning(129) << "KAction::plug called with 0 argument\n"; 00601 return -1; 00602 } 00603 00604 #ifndef NDEBUG 00605 KAccel* kaccel = kaccelCurrent(); 00606 // If there is a shortcut, but no KAccel available 00607 if( !d->m_cut.isNull() && kaccel == 0 ) { 00608 kdWarning(129) << "KAction::plug(): has no KAccel object; this = " << this << " name = " << name() << " parentCollection = " << m_parentCollection << endl; // ellis 00609 kdDebug(129) << kdBacktrace() << endl; 00610 } 00611 #endif 00612 00613 // Check if action is permitted 00614 if (kapp && !kapp->authorizeKAction(name())) 00615 return -1; 00616 00617 plugShortcut(); 00618 00619 if ( w->inherits("QPopupMenu") ) 00620 { 00621 QPopupMenu* menu = static_cast<QPopupMenu*>( w ); 00622 int id; 00623 // Don't insert shortcut into menu if it's already in a KAccel object. 00624 int keyQt = (d->m_kaccelList.count() || d->m_kaccel) ? 0 : d->m_cut.keyCodeQt(); 00625 00626 if ( d->hasIcon() ) 00627 { 00628 KInstance *instance; 00629 if ( m_parentCollection ) 00630 instance = m_parentCollection->instance(); 00631 else 00632 instance = KGlobal::instance(); 00633 id = menu->insertItem( d->iconSet( KIcon::Small, 0, instance ), d->text(), this,//dsweet 00634 SLOT( slotActivated() ), keyQt, 00635 -1, index ); 00636 } 00637 else 00638 id = menu->insertItem( d->text(), this, 00639 SLOT( slotActivated() ), //dsweet 00640 keyQt, -1, index ); 00641 00642 // If the shortcut is already in a KAccel object, then 00643 // we need to set the menu item's shortcut text. 00644 if ( d->m_kaccelList.count() || d->m_kaccel ) 00645 updateShortcut( menu, id ); 00646 00647 // call setItemEnabled only if the item really should be disabled, 00648 // because that method is slow and the item is per default enabled 00649 if ( !d->isEnabled() ) 00650 menu->setItemEnabled( id, false ); 00651 00652 if ( !d->whatsThis().isEmpty() ) 00653 menu->setWhatsThis( id, whatsThisWithIcon() ); 00654 00655 addContainer( menu, id ); 00656 connect( menu, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) ); 00657 00658 if ( m_parentCollection ) 00659 m_parentCollection->connectHighlight( menu, this ); 00660 00661 return d->m_containers.count() - 1; 00662 } 00663 else if ( w->inherits( "KToolBar" ) ) 00664 { 00665 KToolBar *bar = static_cast<KToolBar *>( w ); 00666 00667 int id_ = getToolButtonID(); 00668 KInstance *instance; 00669 if ( m_parentCollection ) 00670 instance = m_parentCollection->instance(); 00671 else 00672 instance = KGlobal::instance(); 00673 00674 if ( icon().isEmpty() && !iconSet().pixmap().isNull() ) // old code using QIconSet directly 00675 { 00676 bar->insertButton( iconSet().pixmap(), id_, SIGNAL( clicked() ), this, 00677 SLOT( slotActivated() ), 00678 d->isEnabled(), d->plainText(), index ); 00679 } 00680 else 00681 { 00682 QString icon = d->iconName(); 00683 if ( icon.isEmpty() ) 00684 icon = "unknown"; 00685 bar->insertButton( icon, id_, SIGNAL( clicked() ), this, 00686 SLOT( slotActivated() ), 00687 d->isEnabled(), d->plainText(), index, instance ); 00688 } 00689 bar->getButton( id_ )->setName( QCString("toolbutton_")+name() ); 00690 00691 if ( !d->whatsThis().isEmpty() ) 00692 QWhatsThis::add( bar->getButton(id_), whatsThisWithIcon() ); 00693 00694 if ( !d->toolTip().isEmpty() ) 00695 QToolTip::add( bar->getButton(id_), d->toolTip() ); 00696 00697 addContainer( bar, id_ ); 00698 00699 connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) ); 00700 00701 if ( m_parentCollection ) 00702 m_parentCollection->connectHighlight( bar, this ); 00703 00704 return containerCount() - 1; 00705 } 00706 00707 return -1; 00708 } 00709 00710 void KAction::unplug( QWidget *w ) 00711 { 00712 int i = findContainer( w ); 00713 if ( i == -1 ) 00714 return; 00715 int id = itemId( i ); 00716 00717 if ( w->inherits( "QPopupMenu" ) ) 00718 { 00719 QPopupMenu *menu = static_cast<QPopupMenu *>( w ); 00720 menu->removeItem( id ); 00721 } 00722 else if ( w->inherits( "KToolBar" ) ) 00723 { 00724 KToolBar *bar = static_cast<KToolBar *>( w ); 00725 bar->removeItemDelayed( id ); 00726 } 00727 else if ( w->inherits( "QMenuBar" ) ) 00728 { 00729 QMenuBar *bar = static_cast<QMenuBar *>( w ); 00730 bar->removeItem( id ); 00731 } 00732 00733 removeContainer( i ); 00734 if ( m_parentCollection ) 00735 m_parentCollection->disconnectHighlight( w, this ); 00736 } 00737 00738 void KAction::plugAccel(KAccel *kacc, bool configurable) 00739 { 00740 kdWarning(129) << "KAction::plugAccel(): call to deprecated action." << endl; 00741 kdDebug(129) << kdBacktrace() << endl; 00742 //kdDebug(129) << "KAction::plugAccel( kacc = " << kacc << " ): name \"" << name() << "\"" << endl; 00743 if ( d->m_kaccel ) 00744 unplugAccel(); 00745 00746 // If the parent collection's accel ptr isn't set yet 00747 //if ( m_parentCollection && !m_parentCollection->accel() ) 00748 // m_parentCollection->setAccel( kacc ); 00749 00750 // We can only plug this action into the given KAccel object 00751 // if it does not already contain an action with the same name. 00752 if ( !kacc->actions().actionPtr(name()) ) 00753 { 00754 d->m_kaccel = kacc; 00755 d->m_kaccel->insert(name(), d->plainText(), QString::null, 00756 KShortcut(d->m_cut), 00757 this, SLOT(slotActivated()), 00758 configurable, isEnabled()); 00759 connect(d->m_kaccel, SIGNAL(destroyed()), this, SLOT(slotDestroyed())); 00760 //connect(d->m_kaccel, SIGNAL(keycodeChanged()), this, SLOT(slotKeycodeChanged())); 00761 } 00762 else 00763 kdWarning(129) << "KAction::plugAccel( kacc = " << kacc << " ): KAccel object already contains an action name \"" << name() << "\"" << endl; // -- ellis 00764 } 00765 00766 void KAction::unplugAccel() 00767 { 00768 //kdDebug(129) << "KAction::unplugAccel() " << this << " " << name() << endl; 00769 if ( d->m_kaccel ) 00770 { 00771 d->m_kaccel->remove(name()); 00772 d->m_kaccel = 0; 00773 } 00774 } 00775 00776 void KAction::plugMainWindowAccel( QWidget *w ) 00777 { 00778 // Note: topLevelWidget() stops too early, we can't use it. 00779 QWidget * tl = w; 00780 QWidget * n; 00781 while ( !tl->isDialog() && ( n = tl->parentWidget() ) ) // lookup parent and store 00782 tl = n; 00783 00784 KMainWindow * mw = dynamic_cast<KMainWindow *>(tl); // try to see if it's a kmainwindow 00785 if (mw) 00786 plugAccel( mw->accel() ); 00787 else 00788 kdDebug(129) << "KAction::plugMainWindowAccel: Toplevel widget isn't a KMainWindow, can't plug accel. " << tl << endl; 00789 } 00790 00791 void KAction::setEnabled(bool enable) 00792 { 00793 //kdDebug(129) << "KAction::setEnabled( " << enable << " ): this = " << this << " d->m_kaccelList.count() = " << d->m_kaccelList.count() << endl; 00794 if ( enable == d->isEnabled() ) 00795 return; 00796 00797 // KDE 4: remove 00798 if (d->m_kaccel) 00799 d->m_kaccel->setEnabled(name(), enable); 00800 // KDE 4: remove end 00801 00802 for ( uint i = 0; i < d->m_kaccelList.count(); i++ ) 00803 d->m_kaccelList[i]->setEnabled( name(), enable ); 00804 00805 d->setEnabled( enable ); 00806 00807 int len = containerCount(); 00808 for( int i = 0; i < len; ++i ) 00809 updateEnabled( i ); 00810 00811 emit enabled( d->isEnabled() ); 00812 } 00813 00814 void KAction::updateEnabled( int i ) 00815 { 00816 QWidget *w = container( i ); 00817 00818 if ( w->inherits("QPopupMenu") ) 00819 static_cast<QPopupMenu*>(w)->setItemEnabled( itemId( i ), d->isEnabled() ); 00820 else if ( w->inherits("QMenuBar") ) 00821 static_cast<QMenuBar*>(w)->setItemEnabled( itemId( i ), d->isEnabled() ); 00822 else if ( w->inherits( "KToolBar" ) ) 00823 static_cast<KToolBar*>(w)->setItemEnabled( itemId( i ), d->isEnabled() ); 00824 } 00825 00826 void KAction::setShortcutConfigurable( bool b ) 00827 { 00828 d->m_configurable = b; 00829 } 00830 00831 void KAction::setText( const QString& text ) 00832 { 00833 // KDE 4: remove 00834 if (d->m_kaccel) { 00835 KAccelAction* pAction = d->m_kaccel->actions().actionPtr(name()); 00836 if (pAction) 00837 pAction->setLabel( text ); 00838 } 00839 // KDE 4: remove end 00840 00841 for( uint i = 0; i < d->m_kaccelList.count(); i++ ) { 00842 KAccelAction* pAction = d->m_kaccelList[i]->actions().actionPtr(name()); 00843 if (pAction) 00844 pAction->setLabel( text ); 00845 } 00846 00847 d->setText( text ); 00848 00849 int len = containerCount(); 00850 for( int i = 0; i < len; ++i ) 00851 updateText( i ); 00852 } 00853 00854 void KAction::updateText( int i ) 00855 { 00856 QWidget *w = container( i ); 00857 00858 if ( w->inherits( "QPopupMenu" ) ) { 00859 int id = itemId( i ); 00860 static_cast<QPopupMenu*>(w)->changeItem( id, d->text() ); 00861 if (!d->m_cut.isNull()) 00862 updateShortcut( static_cast<QPopupMenu*>(w), id ); 00863 } 00864 else if ( w->inherits( "QMenuBar" ) ) 00865 static_cast<QMenuBar*>(w)->changeItem( itemId( i ), d->text() ); 00866 else if ( w->inherits( "KToolBar" ) ) 00867 { 00868 QWidget *button = static_cast<KToolBar *>(w)->getWidget( itemId( i ) ); 00869 if ( button->inherits( "KToolBarButton" ) ) 00870 static_cast<KToolBarButton *>(button)->setText( d->plainText() ); 00871 } 00872 } 00873 00874 QString KAction::text() const 00875 { 00876 return d->text(); 00877 } 00878 00879 QString KAction::plainText() const 00880 { 00881 return d->plainText( ); 00882 } 00883 00884 void KAction::setIcon( const QString &icon ) 00885 { 00886 d->setIconName( icon ); 00887 00888 // now handle any toolbars 00889 int len = containerCount(); 00890 for ( int i = 0; i < len; ++i ) 00891 updateIcon( i ); 00892 } 00893 00894 void KAction::updateIcon( int id ) 00895 { 00896 QWidget* w = container( id ); 00897 00898 if ( w->inherits( "QPopupMenu" ) ) { 00899 int itemId_ = itemId( id ); 00900 static_cast<QPopupMenu*>(w)->changeItem( itemId_, d->iconSet( KIcon::Small ), d->text() ); 00901 if (!d->m_cut.isNull()) 00902 updateShortcut( static_cast<QPopupMenu*>(w), itemId_ ); 00903 } 00904 else if ( w->inherits( "QMenuBar" ) ) 00905 static_cast<QMenuBar*>(w)->changeItem( itemId( id ), d->iconSet( KIcon::Small ), d->text() ); 00906 else if ( w->inherits( "KToolBar" ) ) 00907 static_cast<KToolBar *>(w)->setButtonIcon( itemId( id ), d->iconName() ); 00908 } 00909 00910 QString KAction::icon() const 00911 { 00912 return d->iconName( ); 00913 } 00914 00915 void KAction::setIconSet( const QIconSet &iconset ) 00916 { 00917 d->setIconSet( iconset ); 00918 00919 int len = containerCount(); 00920 for( int i = 0; i < len; ++i ) 00921 updateIconSet( i ); 00922 } 00923 00924 00925 void KAction::updateIconSet( int id ) 00926 { 00927 QWidget *w = container( id ); 00928 00929 if ( w->inherits( "QPopupMenu" ) ) 00930 { 00931 int itemId_ = itemId( id ); 00932 static_cast<QPopupMenu*>(w)->changeItem( itemId_, d->iconSet(), d->text() ); 00933 if (!d->m_cut.isNull()) 00934 updateShortcut( static_cast<QPopupMenu*>(w), itemId_ ); 00935 } 00936 else if ( w->inherits( "QMenuBar" ) ) 00937 static_cast<QMenuBar*>(w)->changeItem( itemId( id ), d->iconSet(), d->text() ); 00938 else if ( w->inherits( "KToolBar" ) ) 00939 { 00940 if ( icon().isEmpty() && d->hasIconSet() ) // only if there is no named icon ( scales better ) 00941 static_cast<KToolBar *>(w)->setButtonIconSet( itemId( id ), d->iconSet() ); 00942 else 00943 static_cast<KToolBar *>(w)->setButtonIconSet( itemId( id ), d->iconSet( KIcon::Small ) ); 00944 } 00945 } 00946 00947 QIconSet KAction::iconSet( KIcon::Group group, int size ) const 00948 { 00949 return d->iconSet( group, size ); 00950 } 00951 00952 bool KAction::hasIcon() const 00953 { 00954 return d->hasIcon(); 00955 } 00956 00957 void KAction::setWhatsThis( const QString& text ) 00958 { 00959 d->setWhatsThis( text ); 00960 00961 int len = containerCount(); 00962 for( int i = 0; i < len; ++i ) 00963 updateWhatsThis( i ); 00964 } 00965 00966 void KAction::updateWhatsThis( int i ) 00967 { 00968 QPopupMenu* pm = popupMenu( i ); 00969 if ( pm ) 00970 { 00971 pm->setWhatsThis( itemId( i ), d->whatsThis() ); 00972 return; 00973 } 00974 00975 KToolBar *tb = toolBar( i ); 00976 if ( tb ) 00977 { 00978 QWidget *w = tb->getButton( itemId( i ) ); 00979 QWhatsThis::remove( w ); 00980 QWhatsThis::add( w, d->whatsThis() ); 00981 return; 00982 } 00983 } 00984 00985 QString KAction::whatsThis() const 00986 { 00987 return d->whatsThis(); 00988 } 00989 00990 QString KAction::whatsThisWithIcon() const 00991 { 00992 QString text = whatsThis(); 00993 if (!d->iconName().isEmpty()) 00994 return QString::fromLatin1("<img source=\"small|%1\"> %2").arg(d->iconName() ).arg(text); 00995 return text; 00996 } 00997 00998 QWidget* KAction::container( int index ) const 00999 { 01000 assert( index < containerCount() ); 01001 return d->m_containers[ index ].m_container; 01002 } 01003 01004 KToolBar* KAction::toolBar( int index ) const 01005 { 01006 return dynamic_cast<KToolBar *>( d->m_containers[ index ].m_container ); 01007 } 01008 01009 QPopupMenu* KAction::popupMenu( int index ) const 01010 { 01011 return dynamic_cast<QPopupMenu *>( d->m_containers[ index ].m_container ); 01012 } 01013 01014 QWidget* KAction::representative( int index ) const 01015 { 01016 return d->m_containers[ index ].m_representative; 01017 } 01018 01019 int KAction::itemId( int index ) const 01020 { 01021 return d->m_containers[ index ].m_id; 01022 } 01023 01024 int KAction::containerCount() const 01025 { 01026 return d->m_containers.count(); 01027 } 01028 01029 uint KAction::kaccelCount() const 01030 { 01031 return d->m_kaccelList.count(); 01032 } 01033 01034 void KAction::addContainer( QWidget* c, int id ) 01035 { 01036 KActionPrivate::Container p; 01037 p.m_container = c; 01038 p.m_id = id; 01039 d->m_containers.append( p ); 01040 } 01041 01042 void KAction::addContainer( QWidget* c, QWidget* w ) 01043 { 01044 KActionPrivate::Container p; 01045 p.m_container = c; 01046 p.m_representative = w; 01047 d->m_containers.append( p ); 01048 } 01049 01050 void KAction::activate() 01051 { 01052 slotActivated(); 01053 } 01054 01055 void KAction::slotActivated() 01056 { 01057 emit activated(); 01058 } 01059 01060 void KAction::slotDestroyed() 01061 { 01062 kdDebug(129) << "KAction::slotDestroyed(): this = " << this << ", name = \"" << name() << "\", sender = " << sender() << endl; 01063 const QObject* o = sender(); 01064 01065 // KDE 4: remove 01066 if ( o == d->m_kaccel ) 01067 { 01068 d->m_kaccel = 0; 01069 return; 01070 } 01071 // KDE 4: remove end 01072 01073 for( uint i = 0; i < d->m_kaccelList.count(); i++ ) 01074 { 01075 if ( o == d->m_kaccelList[i] ) 01076 { 01077 disconnect( d->m_kaccelList[i], SIGNAL(destroyed()), this, SLOT(slotDestroyed()) ); 01078 d->m_kaccelList.remove( d->m_kaccelList.at( i ) ); 01079 return; 01080 } 01081 } 01082 01083 int i; 01084 do 01085 { 01086 i = findContainer( static_cast<const QWidget*>( o ) ); 01087 if ( i != -1 ) 01088 removeContainer( i ); 01089 } while ( i != -1 ); 01090 } 01091 01092 int KAction::findContainer( const QWidget* widget ) const 01093 { 01094 int pos = 0; 01095 QValueList<KActionPrivate::Container>::ConstIterator it = d->m_containers.begin(); 01096 while( it != d->m_containers.end() ) 01097 { 01098 if ( (*it).m_representative == widget || (*it).m_container == widget ) 01099 return pos; 01100 ++it; 01101 ++pos; 01102 } 01103 01104 return -1; 01105 } 01106 01107 void KAction::removeContainer( int index ) 01108 { 01109 int i = 0; 01110 QValueList<KActionPrivate::Container>::Iterator it = d->m_containers.begin(); 01111 while( it != d->m_containers.end() ) 01112 { 01113 if ( i == index ) 01114 { 01115 d->m_containers.remove( it ); 01116 return; 01117 } 01118 ++it; 01119 ++i; 01120 } 01121 } 01122 01123 // FIXME: Remove this (ellis) 01124 void KAction::slotKeycodeChanged() 01125 { 01126 kdDebug(129) << "KAction::slotKeycodeChanged()" << endl; // -- ellis 01127 KAccelAction* pAction = d->m_kaccel->actions().actionPtr(name()); 01128 if( pAction ) 01129 setShortcut(pAction->shortcut()); 01130 } 01131 01132 KActionCollection *KAction::parentCollection() const 01133 { 01134 return m_parentCollection; 01135 } 01136 01137 void KAction::unplugAll() 01138 { 01139 while ( containerCount() != 0 ) 01140 unplug( container( 0 ) ); 01141 } 01142 01143 const KGuiItem& KAction::guiItem() const 01144 { 01145 return *d; 01146 } 01147 01148 void KAction::virtual_hook( int, void* ) 01149 { /*BASE::virtual_hook( id, data );*/ } 01150 01151 /* vim: et sw=2 ts=2 01152 */ 01153 01154 #include "kaction.moc"
KDE Logo
This file is part of the documentation for kdeui Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:43:26 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003