kactionclasses.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               (C) 2003 Andras Mantia <amantia@kde.org>
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Library General Public
00014     License version 2 as published by the Free Software Foundation.
00015 
00016     This library is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019     Library General Public License for more details.
00020 
00021     You should have received a copy of the GNU Library General Public License
00022     along with this library; see the file COPYING.LIB.  If not, write to
00023     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00024     Boston, MA 02110-1301, USA.
00025 */
00026 
00027 #include "kactionclasses.h"
00028 
00029 #include <assert.h>
00030 
00031 #include <qcursor.h>
00032 #include <qclipboard.h>
00033 #include <qfontdatabase.h>
00034 #include <qobjectlist.h>
00035 #include <qwhatsthis.h>
00036 #include <qtimer.h>
00037 #include <qfile.h>
00038 
00039 #include <dcopclient.h>
00040 #include <dcopref.h>
00041 #include <kaccel.h>
00042 #include <kapplication.h>
00043 #include <kconfig.h>
00044 #include <kdebug.h>
00045 #include <kfontcombo.h>
00046 #include <kfontdialog.h>
00047 #include <klocale.h>
00048 #include <kmainwindow.h>
00049 #include <kmenubar.h>
00050 #include <kpopupmenu.h>
00051 #include <ktoolbar.h>
00052 #include <ktoolbarbutton.h>
00053 #include <kurl.h>
00054 #include <kstandarddirs.h>
00055 #include <kstringhandler.h>
00056 
00057 class KToggleAction::KToggleActionPrivate
00058 {
00059 public:
00060   KToggleActionPrivate()
00061   {
00062     m_checked = false;
00063     m_checkedGuiItem = 0;
00064   }
00065 
00066   bool m_checked;
00067   QString m_exclusiveGroup;
00068   KGuiItem* m_checkedGuiItem;
00069 };
00070 
00071 KToggleAction::KToggleAction( const QString& text, const KShortcut& cut,
00072                               QObject* parent,
00073                               const char* name )
00074     : KAction( text, cut, parent, name )
00075 {
00076   d = new KToggleActionPrivate;
00077 }
00078 
00079 KToggleAction::KToggleAction( const QString& text, const KShortcut& cut,
00080                               const QObject* receiver, const char* slot,
00081                               QObject* parent, const char* name )
00082   : KAction( text, cut, receiver, slot, parent, name )
00083 {
00084   d = new KToggleActionPrivate;
00085 }
00086 
00087 KToggleAction::KToggleAction( const QString& text, const QIconSet& pix,
00088                               const KShortcut& cut,
00089                               QObject* parent, const char* name )
00090   : KAction( text, pix, cut, parent, name )
00091 {
00092   d = new KToggleActionPrivate;
00093 }
00094 
00095 KToggleAction::KToggleAction( const QString& text, const QString& pix,
00096                               const KShortcut& cut,
00097                               QObject* parent, const char* name )
00098  : KAction( text, pix, cut, parent, name )
00099 {
00100   d = new KToggleActionPrivate;
00101 }
00102 
00103 KToggleAction::KToggleAction( const QString& text, const QIconSet& pix,
00104                               const KShortcut& cut,
00105                               const QObject* receiver,
00106                               const char* slot, QObject* parent,
00107                               const char* name )
00108   : KAction( text, pix, cut, receiver, slot, parent, name )
00109 {
00110   d = new KToggleActionPrivate;
00111 }
00112 
00113 KToggleAction::KToggleAction( const QString& text, const QString& pix,
00114                               const KShortcut& cut,
00115                               const QObject* receiver,
00116                               const char* slot, QObject* parent,
00117                               const char* name )
00118   : KAction( text, pix, cut, receiver, slot, parent, name )
00119 {
00120   d = new KToggleActionPrivate;
00121 }
00122 
00123 KToggleAction::KToggleAction( QObject* parent, const char* name )
00124     : KAction( parent, name )
00125 {
00126   d = new KToggleActionPrivate;
00127 }
00128 
00129 KToggleAction::~KToggleAction()
00130 {
00131   delete d->m_checkedGuiItem;
00132   delete d;
00133 }
00134 
00135 int KToggleAction::plug( QWidget* widget, int index )
00136 {
00137   if ( !::qt_cast<QPopupMenu *>( widget ) && !::qt_cast<KToolBar *>( widget ) )
00138   {
00139     kdWarning() << "Can not plug KToggleAction in " << widget->className() << endl;
00140     return -1;
00141   }
00142   if (kapp && !kapp->authorizeKAction(name()))
00143     return -1;
00144 
00145   int _index = KAction::plug( widget, index );
00146   if ( _index == -1 )
00147     return _index;
00148 
00149   if ( ::qt_cast<KToolBar *>( widget ) ) {
00150     KToolBar *bar = static_cast<KToolBar *>( widget );
00151 
00152     bar->setToggle( itemId( _index ), true );
00153     bar->setButton( itemId( _index ), isChecked() );
00154   }
00155 
00156   if ( d->m_checked )
00157     updateChecked( _index );
00158 
00159   return _index;
00160 }
00161 
00162 void KToggleAction::setChecked( bool c )
00163 {
00164   if ( c == d->m_checked )
00165     return;
00166   //kdDebug(129) << "KToggleAction::setChecked(" << c << ") " << this << " " << name() << endl;
00167 
00168   d->m_checked = c;
00169 
00170   int len = containerCount();
00171 
00172   for( int i = 0; i < len; ++i )
00173     updateChecked( i );
00174 
00175   if ( c && parent() && !exclusiveGroup().isEmpty() ) {
00176     const QObjectList *list = parent()->children();
00177     if ( list ) {
00178       QObjectListIt it( *list );
00179       for( ; it.current(); ++it ) {
00180           if ( ::qt_cast<KToggleAction *>( it.current() ) && it.current() != this &&
00181             static_cast<KToggleAction*>(it.current())->exclusiveGroup() == exclusiveGroup() ) {
00182       KToggleAction *a = static_cast<KToggleAction*>(it.current());
00183       if( a->isChecked() ) {
00184         a->setChecked( false );
00185         emit a->toggled( false );
00186       }
00187         }
00188       }
00189     }
00190   }
00191 }
00192 
00193 void KToggleAction::updateChecked( int id )
00194 {
00195   QWidget *w = container( id );
00196 
00197   if ( ::qt_cast<QPopupMenu *>( w ) ) {
00198     QPopupMenu* pm = static_cast<QPopupMenu*>(w);
00199     int itemId_ = itemId( id );
00200     if ( !d->m_checkedGuiItem )
00201       pm->setItemChecked( itemId_, d->m_checked );
00202     else {
00203       const KGuiItem* gui = d->m_checked ? d->m_checkedGuiItem : &guiItem();
00204       if ( d->m_checkedGuiItem->hasIcon() )
00205           pm->changeItem( itemId_, gui->iconSet( KIcon::Small ), gui->text() );
00206       else
00207           pm->changeItem( itemId_, gui->text() );
00208 
00209       // If the text doesn't change, then set the icon to be "pressed", otherwise
00210       // there is too little difference between checked and unchecked.
00211       if ( d->m_checkedGuiItem->text() == guiItem().text() )
00212            pm->setItemChecked( itemId_, d->m_checked );
00213 
00214       if ( !d->m_checkedGuiItem->whatsThis().isEmpty() ) // if empty, we keep the initial one
00215           pm->setWhatsThis( itemId_, gui->whatsThis() );
00216       updateShortcut( pm, itemId_ );
00217     }
00218   }
00219   else if ( ::qt_cast<QMenuBar *>( w ) ) // not handled in plug...
00220     static_cast<QMenuBar*>(w)->setItemChecked( itemId( id ), d->m_checked );
00221   else if ( ::qt_cast<KToolBar *>( w ) )
00222   {
00223     QWidget* r = static_cast<KToolBar*>( w )->getButton( itemId( id ) );
00224     if ( r && ::qt_cast<KToolBarButton *>( r ) ) {
00225       static_cast<KToolBar*>( w )->setButton( itemId( id ), d->m_checked );
00226       if ( d->m_checkedGuiItem && d->m_checkedGuiItem->hasIcon() ) {
00227         const KGuiItem* gui = d->m_checked ? d->m_checkedGuiItem : &guiItem();
00228         static_cast<KToolBar*>( w )->setButtonIconSet( itemId( id ), gui->iconSet( KIcon::Toolbar ) );
00229       }
00230     }
00231   }
00232 }
00233 
00234 void KToggleAction::slotActivated()
00235 {
00236   setChecked( !isChecked() );
00237   KAction::slotActivated();
00238   emit toggled( isChecked() );
00239 }
00240 
00241 bool KToggleAction::isChecked() const
00242 {
00243   return d->m_checked;
00244 }
00245 
00246 void KToggleAction::setExclusiveGroup( const QString& name )
00247 {
00248   d->m_exclusiveGroup = name;
00249 }
00250 
00251 QString KToggleAction::exclusiveGroup() const
00252 {
00253   return d->m_exclusiveGroup;
00254 }
00255 
00256 void KToggleAction::setCheckedState( const KGuiItem& checkedItem )
00257 {
00258   delete d->m_checkedGuiItem;
00259   d->m_checkedGuiItem = new KGuiItem( checkedItem );
00260 }
00261 
00262 QString KToggleAction::toolTip() const
00263 {
00264   if ( d->m_checkedGuiItem && d->m_checked )
00265       return d->m_checkedGuiItem->toolTip();
00266   else
00267       return KAction::toolTip();
00268 }
00269 
00270 KRadioAction::KRadioAction( const QString& text, const KShortcut& cut,
00271                             QObject* parent, const char* name )
00272 : KToggleAction( text, cut, parent, name )
00273 {
00274 }
00275 
00276 KRadioAction::KRadioAction( const QString& text, const KShortcut& cut,
00277                             const QObject* receiver, const char* slot,
00278                             QObject* parent, const char* name )
00279 : KToggleAction( text, cut, receiver, slot, parent, name )
00280 {
00281 }
00282 
00283 KRadioAction::KRadioAction( const QString& text, const QIconSet& pix,
00284                             const KShortcut& cut,
00285                             QObject* parent, const char* name )
00286 : KToggleAction( text, pix, cut, parent, name )
00287 {
00288 }
00289 
00290 KRadioAction::KRadioAction( const QString& text, const QString& pix,
00291                             const KShortcut& cut,
00292                             QObject* parent, const char* name )
00293 : KToggleAction( text, pix, cut, parent, name )
00294 {
00295 }
00296 
00297 KRadioAction::KRadioAction( const QString& text, const QIconSet& pix,
00298                             const KShortcut& cut,
00299                             const QObject* receiver, const char* slot,
00300                             QObject* parent, const char* name )
00301 : KToggleAction( text, pix, cut, receiver, slot, parent, name )
00302 {
00303 }
00304 
00305 KRadioAction::KRadioAction( const QString& text, const QString& pix,
00306                             const KShortcut& cut,
00307                             const QObject* receiver, const char* slot,
00308                             QObject* parent, const char* name )
00309 : KToggleAction( text, pix, cut, receiver, slot, parent, name )
00310 {
00311 }
00312 
00313 KRadioAction::KRadioAction( QObject* parent, const char* name )
00314 : KToggleAction( parent, name )
00315 {
00316 }
00317 
00318 void KRadioAction::slotActivated()
00319 {
00320   if ( isChecked() )
00321   {
00322     const QObject *senderObj = sender();
00323 
00324     if ( !senderObj || !::qt_cast<const KToolBarButton *>( senderObj ) )
00325       return;
00326 
00327     const_cast<KToolBarButton *>( static_cast<const KToolBarButton *>( senderObj ) )->on( true );
00328 
00329     return;
00330   }
00331 
00332   KToggleAction::slotActivated();
00333 }
00334 
00335 class KSelectAction::KSelectActionPrivate
00336 {
00337 public:
00338   KSelectActionPrivate()
00339   {
00340     m_edit = false;
00341     m_menuAccelsEnabled = true;
00342     m_menu = 0;
00343     m_current = -1;
00344     m_comboWidth = -1;
00345     m_maxComboViewCount = -1;
00346   }
00347   bool m_edit;
00348   bool m_menuAccelsEnabled;
00349   QPopupMenu *m_menu;
00350   int m_current;
00351   int m_comboWidth;
00352   QStringList m_list;
00353   int m_maxComboViewCount;
00354 
00355   QString makeMenuText( const QString &_text )
00356   {
00357       if ( m_menuAccelsEnabled )
00358         return _text;
00359       QString text = _text;
00360       uint i = 0;
00361       while ( i < text.length() ) {
00362           if ( text[ i ] == '&' ) {
00363               text.insert( i, '&' );
00364               i += 2;
00365           }
00366           else
00367               ++i;
00368       }
00369       return text;
00370   }
00371 };
00372 
00373 KSelectAction::KSelectAction( const QString& text, const KShortcut& cut,
00374                               QObject* parent, const char* name )
00375   : KAction( text, cut, parent, name )
00376 {
00377   d = new KSelectActionPrivate;
00378 }
00379 
00380 KSelectAction::KSelectAction( const QString& text, const KShortcut& cut,
00381                               const QObject* receiver, const char* slot,
00382                               QObject* parent, const char* name )
00383   : KAction( text, cut, receiver, slot, parent, name )
00384 {
00385   d = new KSelectActionPrivate;
00386 }
00387 
00388 KSelectAction::KSelectAction( const QString& text, const QIconSet& pix,
00389                               const KShortcut& cut,
00390                               QObject* parent, const char* name )
00391   : KAction( text, pix, cut, parent, name )
00392 {
00393   d = new KSelectActionPrivate;
00394 }
00395 
00396 KSelectAction::KSelectAction( const QString& text, const QString& pix,
00397                               const KShortcut& cut,
00398                               QObject* parent, const char* name )
00399   : KAction( text, pix, cut, parent, name )
00400 {
00401   d = new KSelectActionPrivate;
00402 }
00403 
00404 KSelectAction::KSelectAction( const QString& text, const QIconSet& pix,
00405                               const KShortcut& cut,
00406                               const QObject* receiver,
00407                               const char* slot, QObject* parent,
00408                               const char* name )
00409   : KAction( text, pix, cut, receiver, slot, parent, name )
00410 {
00411   d = new KSelectActionPrivate;
00412 }
00413 
00414 KSelectAction::KSelectAction( const QString& text, const QString& pix,
00415                               const KShortcut& cut,
00416                               const QObject* receiver,
00417                               const char* slot, QObject* parent,
00418                               const char* name )
00419   : KAction( text, pix, cut, receiver, slot, parent, name )
00420 {
00421   d = new KSelectActionPrivate;
00422 }
00423 
00424 KSelectAction::KSelectAction( QObject* parent, const char* name )
00425   : KAction( parent, name )
00426 {
00427   d = new KSelectActionPrivate;
00428 }
00429 
00430 KSelectAction::~KSelectAction()
00431 {
00432   assert(d);
00433   delete d->m_menu;
00434   delete d; d = 0;
00435 }
00436 
00437 void KSelectAction::setCurrentItem( int id )
00438 {
00439     if ( id >= (int)d->m_list.count() ) {
00440         Q_ASSERT(id < (int)d->m_list.count());
00441         return;
00442     }
00443 
00444     if ( d->m_menu )
00445     {
00446         if ( d->m_current >= 0 )
00447             d->m_menu->setItemChecked( d->m_current, false );
00448         if ( id >= 0 )
00449             d->m_menu->setItemChecked( id, true );
00450     }
00451 
00452     d->m_current = id;
00453 
00454     int len = containerCount();
00455 
00456     for( int i = 0; i < len; ++i )
00457         updateCurrentItem( i );
00458 
00459     //    emit KAction::activated();
00460     //    emit activated( currentItem() );
00461     //    emit activated( currentText() );
00462 }
00463 
00464 void KSelectAction::setComboWidth( int width )
00465 {
00466   if ( width < 0 )
00467     return;
00468 
00469   d->m_comboWidth=width;
00470 
00471   int len = containerCount();
00472 
00473   for( int i = 0; i < len; ++i )
00474     updateComboWidth( i );
00475 
00476 }
00477 
00478 void KSelectAction::setMaxComboViewCount( int n )
00479 {
00480   d->m_maxComboViewCount = n;
00481 }
00482 
00483 QPopupMenu* KSelectAction::popupMenu() const
00484 {
00485     kdDebug(129) << "KAction::popupMenu()" << endl; // remove -- ellis
00486   if ( !d->m_menu )
00487   {
00488     d->m_menu = new KPopupMenu(0L, "KSelectAction::popupMenu()");
00489     setupMenu();
00490     if ( d->m_current >= 0 )
00491       d->m_menu->setItemChecked( d->m_current, true );
00492   }
00493 
00494   return d->m_menu;
00495 }
00496 
00497 void KSelectAction::setupMenu() const
00498 {
00499     if ( !d->m_menu )
00500         return;
00501     d->m_menu->clear();
00502 
00503     QStringList::ConstIterator it = d->m_list.begin();
00504     for( uint id = 0; it != d->m_list.end(); ++it, ++id ) {
00505         QString text = *it;
00506         if ( !text.isEmpty() )
00507             d->m_menu->insertItem( d->makeMenuText( text ), this, SLOT( slotActivated( int ) ), 0, id );
00508         else
00509             d->m_menu->insertSeparator();
00510     }
00511 }
00512 
00513 void KSelectAction::changeItem( int index, const QString& text )
00514 {
00515   if ( index < 0 || index >= (int)d->m_list.count() )
00516   {
00517     kdWarning() << "KSelectAction::changeItem Index out of scope" << endl;
00518     return;
00519   }
00520 
00521   d->m_list[ index ] = text;
00522 
00523   if ( d->m_menu )
00524     d->m_menu->changeItem( index, d->makeMenuText( text ) );
00525 
00526   int len = containerCount();
00527   for( int i = 0; i < len; ++i )
00528     changeItem( i, index, text );
00529 }
00530 
00531 void KSelectAction::changeItem( int id, int index, const QString& text)
00532 {
00533   if ( index < 0 )
00534         return;
00535 
00536   QWidget* w = container( id );
00537   if ( ::qt_cast<KToolBar *>( w ) )
00538   {
00539      QWidget* r = (static_cast<KToolBar*>( w ))->getWidget( itemId( id ) );
00540      if ( ::qt_cast<QComboBox *>( r ) )
00541      {
00542         QComboBox *b = static_cast<QComboBox*>( r );
00543         b->changeItem(text, index );
00544      }
00545   }
00546 }
00547 
00548 void KSelectAction::setItems( const QStringList &lst )
00549 {
00550   d->m_list = lst;
00551   d->m_current = -1;
00552 
00553   setupMenu();
00554 
00555   int len = containerCount();
00556   for( int i = 0; i < len; ++i )
00557     updateItems( i );
00558 
00559   // Disable if empty and not editable
00560   setEnabled ( lst.count() > 0 || d->m_edit );
00561 }
00562 
00563 QStringList KSelectAction::items() const
00564 {
00565   return d->m_list;
00566 }
00567 
00568 QString KSelectAction::currentText() const
00569 {
00570   if ( currentItem() < 0 )
00571     return QString::null;
00572 
00573   return d->m_list[ currentItem() ];
00574 }
00575 
00576 int KSelectAction::currentItem() const
00577 {
00578   return d->m_current;
00579 }
00580 
00581 void KSelectAction::updateCurrentItem( int id )
00582 {
00583   if ( d->m_current < 0 )
00584         return;
00585 
00586   QWidget* w = container( id );
00587   if ( ::qt_cast<KToolBar *>( w ) ) {
00588     QWidget* r = static_cast<KToolBar*>( w )->getWidget( itemId( id ) );
00589     if ( ::qt_cast<QComboBox *>( r ) ) {
00590       QComboBox *b = static_cast<QComboBox*>( r );
00591       b->setCurrentItem( d->m_current );
00592     }
00593   }
00594 }
00595 
00596 int KSelectAction::comboWidth() const
00597 {
00598   return d->m_comboWidth;
00599 }
00600 
00601 void KSelectAction::updateComboWidth( int id )
00602 {
00603   QWidget* w = container( id );
00604   if ( ::qt_cast<KToolBar *>( w ) ) {
00605     QWidget* r = static_cast<KToolBar*>( w )->getWidget( itemId( id ) );
00606     if ( ::qt_cast<QComboBox *>( r ) ) {
00607       QComboBox *cb = static_cast<QComboBox*>( r );
00608       cb->setMinimumWidth( d->m_comboWidth );
00609       cb->setMaximumWidth( d->m_comboWidth );
00610     }
00611   }
00612 }
00613 
00614 void KSelectAction::updateItems( int id )
00615 {
00616   kdDebug(129) << "KAction::updateItems( " << id << ", lst )" << endl; // remove -- ellis
00617   QWidget* w = container( id );
00618   if ( ::qt_cast<KToolBar *>( w ) ) {
00619     QWidget* r = static_cast<KToolBar*>( w )->getWidget( itemId( id ) );
00620     if ( ::qt_cast<QComboBox *>( r ) ) {
00621       QComboBox *cb = static_cast<QComboBox*>( r );
00622       cb->clear();
00623       QStringList lst = comboItems();
00624       QStringList::ConstIterator it = lst.begin();
00625       for( ; it != lst.end(); ++it )
00626         cb->insertItem( *it );
00627       // qt caches and never recalculates the sizeHint()
00628       // qcombobox.cpp recommends calling setFont to invalidate the sizeHint
00629       // setFont sets own_font = True, so we're a bit mean and calll
00630       // unsetFont which calls setFont and then overwrites the own_font
00631       cb->unsetFont();
00632     }
00633    }
00634 }
00635 
00636 int KSelectAction::plug( QWidget *widget, int index )
00637 {
00638   if (kapp && !kapp->authorizeKAction(name()))
00639     return -1;
00640   kdDebug(129) << "KSelectAction::plug( " << widget << ", " << index << " )" << endl; // remove -- ellis
00641   if ( ::qt_cast<QPopupMenu *>( widget) )
00642   {
00643     // Create the PopupMenu and store it in m_menu
00644     (void)popupMenu();
00645 
00646     QPopupMenu* menu = static_cast<QPopupMenu*>( widget );
00647     int id;
00648     if ( hasIcon() )
00649       id = menu->insertItem( iconSet(), text(), d->m_menu, -1, index );
00650     else
00651       id = menu->insertItem( text(), d->m_menu, -1, index );
00652 
00653     if ( !isEnabled() )
00654         menu->setItemEnabled( id, false );
00655 
00656     QString wth = whatsThis();
00657     if ( !wth.isEmpty() )
00658         menu->setWhatsThis( id, wth );
00659 
00660     addContainer( menu, id );
00661     connect( menu, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
00662 
00663     return containerCount() - 1;
00664   }
00665   else if ( ::qt_cast<KToolBar *>( widget ) )
00666   {
00667     KToolBar* bar = static_cast<KToolBar*>( widget );
00668     int id_ = KAction::getToolButtonID();
00669     bar->insertCombo( comboItems(), id_, isEditable(),
00670                       SIGNAL( activated( const QString & ) ), this,
00671                       SLOT( slotActivated( const QString & ) ), isEnabled(),
00672                       toolTip(), -1, index );
00673 
00674     QComboBox *cb = bar->getCombo( id_ );
00675     if ( cb )
00676     {
00677       if (!isEditable()) cb->setFocusPolicy(QWidget::NoFocus);
00678       cb->setMinimumWidth( cb->sizeHint().width() );
00679       if ( d->m_comboWidth > 0 )
00680       {
00681         cb->setMinimumWidth( d->m_comboWidth );
00682         cb->setMaximumWidth( d->m_comboWidth );
00683       }
00684       cb->setInsertionPolicy( QComboBox::NoInsertion );
00685       QWhatsThis::add( cb, whatsThis() );
00686       if ( d->m_maxComboViewCount != -1 ) cb->setSizeLimit( d->m_maxComboViewCount );
00687     }
00688 
00689     addContainer( bar, id_ );
00690 
00691     connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
00692 
00693     updateCurrentItem( containerCount() - 1 );
00694 
00695     return containerCount() - 1;
00696   }
00697   else if ( ::qt_cast<QMenuBar *>( widget ) )
00698   {
00699     // Create the PopupMenu and store it in m_menu
00700     (void)popupMenu();
00701 
00702     QMenuBar* menu = static_cast<QMenuBar*>( widget );
00703     int id = menu->insertItem( text(), d->m_menu, -1, index );
00704 
00705     if ( !isEnabled() )
00706         menu->setItemEnabled( id, false );
00707 
00708     QString wth = whatsThis();
00709     if ( !wth.isEmpty() )
00710         menu->setWhatsThis( id, wth );
00711 
00712     addContainer( menu, id );
00713     connect( menu, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
00714 
00715     return containerCount() - 1;
00716   }
00717 
00718   kdWarning() << "Can not plug KAction in " << widget->className() << endl;
00719   return -1;
00720 }
00721 
00722 QStringList KSelectAction::comboItems() const
00723 {
00724   if( d->m_menuAccelsEnabled ) {
00725     QStringList lst;
00726     QStringList::ConstIterator it = d->m_list.begin();
00727     for( ; it != d->m_list.end(); ++it )
00728     {
00729       QString item = *it;
00730       int i = item.find( '&' );
00731       if ( i > -1 )
00732         item = item.remove( i, 1 );
00733       lst.append( item );
00734     }
00735     return lst;
00736   }
00737   else
00738     return d->m_list;
00739 }
00740 
00741 void KSelectAction::clear()
00742 {
00743   if ( d->m_menu )
00744     d->m_menu->clear();
00745 
00746   int len = containerCount();
00747   for( int i = 0; i < len; ++i )
00748     updateClear( i );
00749 }
00750 
00751 void KSelectAction::updateClear( int id )
00752 {
00753   QWidget* w = container( id );
00754   if ( ::qt_cast<KToolBar *>( w ) ) {
00755     QWidget* r = static_cast<KToolBar*>( w )->getWidget( itemId( id ) );
00756     if ( ::qt_cast<QComboBox *>( r ) ) {
00757       QComboBox *b = static_cast<QComboBox*>( r );
00758       b->clear();
00759     }
00760   }
00761 }
00762 
00763 void KSelectAction::slotActivated( int id )
00764 {
00765   if ( d->m_current == id )
00766     return;
00767 
00768   setCurrentItem( id );
00769   // Delay this. Especially useful when the slot connected to activated() will re-create
00770   // the menu, e.g. in the recent files action. This prevents a crash.
00771   QTimer::singleShot( 0, this, SLOT( slotActivated() ) );
00772 }
00773 
00774 void KSelectAction::slotActivated( const QString &text )
00775 {
00776   if ( isEditable() )
00777   {
00778     QStringList lst = d->m_list;
00779     if(!lst.contains(text))
00780     {
00781       lst.append( text );
00782       setItems( lst );
00783     }
00784   }
00785 
00786   int i = d->m_list.findIndex( text );
00787   if ( i > -1 )
00788       setCurrentItem( i );
00789   else
00790       setCurrentItem( comboItems().findIndex( text ) );
00791   // Delay this. Especially useful when the slot connected to activated() will re-create
00792   // the menu, e.g. in the recent files action. This prevents a crash.
00793   QTimer::singleShot( 0, this, SLOT( slotActivated() ) );
00794 }
00795 
00796 void KSelectAction::slotActivated()
00797 {
00798   KAction::slotActivated();
00799   kdDebug(129) << "KSelectAction::slotActivated currentItem=" << currentItem() << " currentText=" << currentText() << endl;
00800   emit activated( currentItem() );
00801   emit activated( currentText() );
00802 }
00803 
00804 void KSelectAction::setEditable( bool edit )
00805 {
00806   d->m_edit = edit;
00807 }
00808 
00809 bool KSelectAction::isEditable() const
00810 {
00811   return d->m_edit;
00812 }
00813 
00814 void KSelectAction::setRemoveAmpersandsInCombo( bool b )
00815 {
00816   setMenuAccelsEnabled( b );
00817 }
00818 
00819 bool KSelectAction::removeAmpersandsInCombo() const
00820 {
00821   return menuAccelsEnabled( );
00822 }
00823 
00824 void KSelectAction::setMenuAccelsEnabled( bool b )
00825 {
00826   d->m_menuAccelsEnabled = b;
00827 }
00828 
00829 bool KSelectAction::menuAccelsEnabled() const
00830 {
00831   return d->m_menuAccelsEnabled;
00832 }
00833 
00834 class KListAction::KListActionPrivate
00835 {
00836 public:
00837   KListActionPrivate()
00838   {
00839     m_current = 0;
00840   }
00841   int m_current;
00842 };
00843 
00844 KListAction::KListAction( const QString& text, const KShortcut& cut,
00845                           QObject* parent, const char* name )
00846   : KSelectAction( text, cut, parent, name )
00847 {
00848   d = new KListActionPrivate;
00849 }
00850 
00851 KListAction::KListAction( const QString& text, const KShortcut& cut,
00852                           const QObject* receiver, const char* slot,
00853                           QObject* parent, const char* name )
00854   : KSelectAction( text, cut, parent, name )
00855 {
00856   d = new KListActionPrivate;
00857   if ( receiver )
00858     connect( this, SIGNAL( activated( int ) ), receiver, slot );
00859 }
00860 
00861 KListAction::KListAction( const QString& text, const QIconSet& pix,
00862                           const KShortcut& cut,
00863                           QObject* parent, const char* name )
00864   : KSelectAction( text, pix, cut, parent, name )
00865 {
00866   d = new KListActionPrivate;
00867 }
00868 
00869 KListAction::KListAction( const QString& text, const QString& pix,
00870                           const KShortcut& cut,
00871                           QObject* parent, const char* name )
00872   : KSelectAction( text, pix, cut, parent, name )
00873 {
00874   d = new KListActionPrivate;
00875 }
00876 
00877 KListAction::KListAction( const QString& text, const QIconSet& pix,
00878                           const KShortcut& cut, const QObject* receiver,
00879                           const char* slot, QObject* parent,
00880                           const char* name )
00881   : KSelectAction( text, pix, cut, parent, name )
00882 {
00883   d = new KListActionPrivate;
00884   if ( receiver )
00885     connect( this, SIGNAL( activated( int ) ), receiver, slot );
00886 }
00887 
00888 KListAction::KListAction( const QString& text, const QString& pix,
00889                           const KShortcut& cut, const QObject* receiver,
00890                           const char* slot, QObject* parent,
00891                           const char* name )
00892   : KSelectAction( text, pix, cut, parent, name )
00893 {
00894   d = new KListActionPrivate;
00895   if ( receiver )
00896     connect( this, SIGNAL( activated( int ) ), receiver, slot );
00897 }
00898 
00899 KListAction::KListAction( QObject* parent, const char* name )
00900   : KSelectAction( parent, name )
00901 {
00902   d = new KListActionPrivate;
00903 }
00904 
00905 KListAction::~KListAction()
00906 {
00907   delete d; d = 0;
00908 }
00909 
00910 void KListAction::setCurrentItem( int index )
00911 {
00912   KSelectAction::setCurrentItem( index );
00913   d->m_current = index;
00914 
00915   //  emit KAction::activated();
00916   //  emit activated( currentItem() );
00917   // emit activated( currentText() );
00918 }
00919 
00920 QString KListAction::currentText() const
00921 {
00922   return KSelectAction::currentText();
00923 }
00924 
00925 int KListAction::currentItem() const
00926 {
00927   return d->m_current;
00928 }
00929 
00930 class KRecentFilesAction::KRecentFilesActionPrivate
00931 {
00932 public:
00933   KRecentFilesActionPrivate()
00934   {
00935     m_maxItems = 0;
00936     m_popup = 0;
00937   }
00938   uint m_maxItems;
00939   KPopupMenu *m_popup;
00940   QMap<QString, QString> m_shortNames;
00941   QMap<QString, KURL> m_urls;
00942 };
00943 
00944 KRecentFilesAction::KRecentFilesAction( const QString& text,
00945                                         const KShortcut& cut,
00946                                         QObject* parent, const char* name,
00947                                         uint maxItems )
00948   : KListAction( text, cut, parent, name)
00949 {
00950   d = new KRecentFilesActionPrivate;
00951   d->m_maxItems = maxItems;
00952 
00953   init();
00954 }
00955 
00956 KRecentFilesAction::KRecentFilesAction( const QString& text,
00957                                         const KShortcut& cut,
00958                                         const QObject* receiver,
00959                                         const char* slot,
00960                                         QObject* parent, const char* name,
00961                                         uint maxItems )
00962   : KListAction( text, cut, parent, name)
00963 {
00964   d = new KRecentFilesActionPrivate;
00965   d->m_maxItems = maxItems;
00966 
00967   init();
00968 
00969   if ( receiver )
00970     connect( this,     SIGNAL(urlSelected(const KURL&)),
00971              receiver, slot );
00972 }
00973 
00974 KRecentFilesAction::KRecentFilesAction( const QString& text,
00975                                         const QIconSet& pix,
00976                                         const KShortcut& cut,
00977