kdeui Library API Documentation

ktoolbar.cpp

00001 /* This file is part of the KDE libraries
00002     Copyright
00003     (C) 2000 Reginald Stadlbauer (reggie@kde.org)
00004     (C) 1997, 1998 Stephan Kulow (coolo@kde.org)
00005     (C) 1997, 1998 Mark Donohoe (donohoe@kde.org)
00006     (C) 1997, 1998 Sven Radej (radej@kde.org)
00007     (C) 1997, 1998 Matthias Ettrich (ettrich@kde.org)
00008     (C) 1999 Chris Schlaeger (cs@kde.org)
00009     (C) 1999 Kurt Granroth (granroth@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 <config.h>
00027 
00028 #ifdef KDE_USE_FINAL
00029 #undef Always
00030 #include <qdockwindow.h>
00031 #endif
00032 #include "ktoolbar.h"
00033 #include "kmainwindow.h"
00034 
00035 #include <string.h>
00036 
00037 #include <qpainter.h>
00038 #include <qtooltip.h>
00039 #include <qdrawutil.h>
00040 #include <qstring.h>
00041 #include <qrect.h>
00042 #include <qobjectlist.h>
00043 #include <qtimer.h>
00044 #include <qstyle.h>
00045 
00046 #include "klineedit.h"
00047 #include "kseparator.h"
00048 #include <klocale.h>
00049 #include <kapplication.h>
00050 #include <kaction.h>
00051 #include <kstdaction.h>
00052 #include <kglobal.h>
00053 #include <kconfig.h>
00054 #include <kiconloader.h>
00055 #include <kcombobox.h>
00056 #include <kpopupmenu.h>
00057 #include <kanimwidget.h>
00058 
00059 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00060 #include <kipc.h> // schroder
00061 #endif
00062 
00063 #include <kwin.h>
00064 #include <kdebug.h>
00065 #include <qlayout.h>
00066 
00067 #include "ktoolbarbutton.h"
00068 
00069 enum {
00070     CONTEXT_TOP = 0,
00071     CONTEXT_LEFT = 1,
00072     CONTEXT_RIGHT = 2,
00073     CONTEXT_BOTTOM = 3,
00074     CONTEXT_FLOAT = 4,
00075     CONTEXT_FLAT = 5,
00076     CONTEXT_ICONS = 6,
00077     CONTEXT_TEXT = 7,
00078     CONTEXT_TEXTRIGHT = 8,
00079     CONTEXT_TEXTUNDER = 9,
00080     CONTEXT_ICONSIZES = 50 // starting point for the icon size list, put everything else before
00081 };
00082 
00083 class KToolBarPrivate
00084 {
00085 public:
00086     KToolBarPrivate() {
00087         m_iconSize     = 0;
00088         m_iconText     = KToolBar::IconOnly;
00089         m_highlight    = true;
00090         m_transparent  = true;
00091         m_honorStyle   = false;
00092 
00093         m_enableContext  = true;
00094 
00095         m_xmlguiClient   = 0;
00096         m_configurePlugged = false;
00097 
00098         oldPos = Qt::DockUnmanaged;
00099 
00100         modified = m_isHorizontal = positioned = false;
00101 
00102         IconSizeDefault = 0;
00103         IconTextDefault = "IconOnly";
00104 
00105         NewLineDefault = false;
00106         OffsetDefault = 0;
00107         PositionDefault = "Top";
00108     HiddenDefault = false;
00109         idleButtons.setAutoDelete(true);
00110     }
00111 
00112     int m_iconSize;
00113     KToolBar::IconText m_iconText;
00114     bool m_highlight : 1;
00115     bool m_transparent : 1;
00116     bool m_honorStyle : 1;
00117     bool m_isHorizontal : 1;
00118     bool m_enableContext : 1;
00119     bool m_configurePlugged : 1;
00120     bool modified : 1;
00121     bool positioned : 1;
00122 
00123     QWidget *m_parent;
00124 
00125     QMainWindow::ToolBarDock oldPos;
00126 
00127     KXMLGUIClient *m_xmlguiClient;
00128 
00129     struct ToolBarInfo
00130     {
00131         ToolBarInfo() : index( -1 ), offset( -1 ), newline( false ), dock( Qt::DockTop ) {}
00132         ToolBarInfo( Qt::Dock d, int i, bool n, int o ) : index( i ), offset( o ), newline( n ), dock( d ) {}
00133         int index, offset;
00134         bool newline;
00135         Qt::Dock dock;
00136     };
00137 
00138     ToolBarInfo toolBarInfo;
00139     QValueList<int> iconSizes;
00140     QTimer repaintTimer;
00141 
00142   // Default Values.
00143   bool HiddenDefault;
00144   int IconSizeDefault;
00145   QString IconTextDefault;
00146   bool NewLineDefault;
00147   int OffsetDefault;
00148   QString PositionDefault;
00149 
00150    QPtrList<QWidget> idleButtons;
00151 };
00152 
00153 KToolBarSeparator::KToolBarSeparator(Orientation o , bool l, QToolBar *parent,
00154                                      const char* name )
00155     :QFrame( parent, name ), line( l )
00156 {
00157     connect( parent, SIGNAL(orientationChanged(Orientation)),
00158              this, SLOT(setOrientation(Orientation)) );
00159     setOrientation( o );
00160     setBackgroundMode( parent->backgroundMode() );
00161     setBackgroundOrigin( ParentOrigin );
00162 }
00163 
00164 void KToolBarSeparator::setOrientation( Orientation o )
00165 {
00166     orient = o;
00167     setFrameStyle( NoFrame );
00168 }
00169 
00170 void KToolBarSeparator::drawContents( QPainter* p )
00171 {
00172     if ( line ) {
00173         QStyle::SFlags flags = QStyle::Style_Default;
00174 
00175         if ( orientation() == Horizontal )
00176             flags = flags | QStyle::Style_Horizontal;
00177 
00178         style().drawPrimitive(QStyle::PE_DockWindowSeparator, p,
00179                               contentsRect(), colorGroup(), flags);
00180     } else {
00181         QFrame::drawContents(p);
00182     }
00183 }
00184 
00185 void KToolBarSeparator::styleChange( QStyle& )
00186 {
00187     setOrientation( orient );
00188 }
00189 
00190 QSize KToolBarSeparator::sizeHint() const
00191 {
00192     int dim = style().pixelMetric( QStyle::PM_DockWindowSeparatorExtent, this );
00193     return orientation() == Vertical ? QSize( 0, dim ) : QSize( dim, 0 );
00194 }
00195 
00196 QSizePolicy KToolBarSeparator::sizePolicy() const
00197 {
00198     return QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
00199 }
00200 
00201 KToolBar::KToolBar( QWidget *parent, const char *name, bool honorStyle, bool readConfig )
00202     : QToolBar( QString::fromLatin1( name ),
00203       dynamic_cast<QMainWindow*>(parent),
00204       parent, false,
00205       name ? name : "mainToolBar")
00206 {
00207     init( readConfig, honorStyle );
00208 }
00209 
00210 KToolBar::KToolBar( QMainWindow *parentWindow, QMainWindow::ToolBarDock dock, bool newLine, const char *name, bool honorStyle, bool readConfig )
00211     : QToolBar( QString::fromLatin1( name ),
00212       parentWindow, dock, newLine,
00213       name ? name : "mainToolBar")
00214 {
00215     init( readConfig, honorStyle );
00216 }
00217 
00218 KToolBar::KToolBar( QMainWindow *parentWindow, QWidget *dock, bool newLine, const char *name, bool honorStyle, bool readConfig )
00219     : QToolBar( QString::fromLatin1( name ),
00220       parentWindow, dock, newLine,
00221       name ? name : "mainToolBar")
00222 {
00223     init( readConfig, honorStyle );
00224 }
00225 
00226 KToolBar::~KToolBar()
00227 {
00228     emit toolbarDestroyed();
00229     delete d;
00230 }
00231 
00232 void KToolBar::init( bool readConfig, bool honorStyle )
00233 {
00234     d = new KToolBarPrivate;
00235     // Get the default iconSize sense m_iconSize == 0 which isn't the default
00236     d->IconSizeDefault = iconSize();
00237     setFullSize( true );
00238     d->m_honorStyle = honorStyle;
00239     context = 0;
00240     layoutTimer = new QTimer( this );
00241     connect( layoutTimer, SIGNAL( timeout() ),
00242              this, SLOT( rebuildLayout() ) );
00243     connect( &(d->repaintTimer), SIGNAL( timeout() ),
00244              this, SLOT( slotRepaint() ) );
00245 
00246     if ( kapp ) { // may be null when started inside designer
00247         connect(kapp, SIGNAL(toolbarAppearanceChanged(int)), this, SLOT(slotAppearanceChanged()));
00248         // request notification of changes in icon style
00249 #if defined Q_WS_X11 && ! defined K_WS_QTONLY
00250         kapp->addKipcEventMask(KIPC::IconChanged);
00251 #endif
00252         connect(kapp, SIGNAL(iconChanged(int)), this, SLOT(slotIconChanged(int)));
00253     }
00254 
00255     // finally, read in our configurable settings
00256     if ( readConfig )
00257         slotReadConfig();
00258 
00259     if ( mainWindow() )
00260         connect( mainWindow(), SIGNAL( toolBarPositionChanged( QToolBar * ) ),
00261                  this, SLOT( toolBarPosChanged( QToolBar * ) ) );
00262 
00263     // Hack to make sure we recalculate our size when we dock.
00264     connect( this, SIGNAL(placeChanged(QDockWindow::Place)), SLOT(rebuildLayout()) );
00265 }
00266 
00267 int KToolBar::insertButton(const QString& icon, int id, bool enabled,
00268                             const QString& text, int index, KInstance *_instance )
00269 {
00270     KToolBarButton *button = new KToolBarButton( icon, id, this, 0, text, _instance );
00271 
00272     insertWidgetInternal( button, index, id );
00273     button->setEnabled( enabled );
00274     doConnections( button );
00275     return index;
00276 }
00277 
00278 
00279 int KToolBar::insertButton(const QString& icon, int id, const char *signal,
00280                             const QObject *receiver, const char *slot,
00281                             bool enabled, const QString& text, int index, KInstance *_instance )
00282 {
00283     KToolBarButton *button = new KToolBarButton( icon, id, this, 0, text, _instance);
00284     insertWidgetInternal( button, index, id );
00285     button->setEnabled( enabled );
00286     connect( button, signal, receiver, slot );
00287     doConnections( button );
00288     return index;
00289 }
00290 
00291 
00292 int KToolBar::insertButton(const QPixmap& pixmap, int id, bool enabled,
00293                             const QString& text, int index )
00294 {
00295     KToolBarButton *button = new KToolBarButton( pixmap, id, this, 0, text);
00296     insertWidgetInternal( button, index, id );
00297     button->setEnabled( enabled );
00298     doConnections( button );
00299     return index;
00300 }
00301 
00302 
00303 int KToolBar::insertButton(const QPixmap& pixmap, int id, const char *signal,
00304                             const QObject *receiver, const char *slot,
00305                             bool enabled, const QString& text,
00306                             int index )
00307 {
00308     KToolBarButton *button = new KToolBarButton( pixmap, id, this, 0, text);
00309     insertWidgetInternal( button, index, id );
00310     button->setEnabled( enabled );
00311     connect( button, signal, receiver, slot );
00312     doConnections( button );
00313     return index;
00314 }
00315 
00316 
00317 int KToolBar::insertButton(const QString& icon, int id, QPopupMenu *popup,
00318                             bool enabled, const QString &text, int index )
00319 {
00320     KToolBarButton *button = new KToolBarButton( icon, id, this, 0, text );
00321     insertWidgetInternal( button, index, id );
00322     button->setEnabled( enabled );
00323     button->setPopup( popup );
00324     doConnections( button );
00325     return index;
00326 }
00327 
00328 
00329 int KToolBar::insertButton(const QPixmap& pixmap, int id, QPopupMenu *popup,
00330                             bool enabled, const QString &text, int index )
00331 {
00332     KToolBarButton *button = new KToolBarButton( pixmap, id, this, 0, text );
00333     insertWidgetInternal( button, index, id );
00334     button->setEnabled( enabled );
00335     button->setPopup( popup );
00336     doConnections( button );
00337     return index;
00338 }
00339 
00340 
00341 int KToolBar::insertLined (const QString& text, int id,
00342                             const char *signal,
00343                             const QObject *receiver, const char *slot,
00344                             bool enabled ,
00345                             const QString& toolTipText,
00346                             int size, int index )
00347 {
00348     KLineEdit *lined = new KLineEdit ( this, 0 );
00349     if ( !toolTipText.isEmpty() )
00350         QToolTip::add( lined, toolTipText );
00351     if ( size > 0 )
00352         lined->setMinimumWidth( size );
00353     insertWidgetInternal( lined, index, id );
00354     connect( lined, signal, receiver, slot );
00355     lined->setText(text);
00356     lined->setEnabled( enabled );
00357     return index;
00358 }
00359 
00360 int KToolBar::insertCombo (const QStringList &list, int id, bool writable,
00361                             const char *signal, const QObject *receiver,
00362                             const char *slot, bool enabled,
00363                             const QString& tooltiptext,
00364                             int size, int index,
00365                             QComboBox::Policy policy )
00366 {
00367     KComboBox *combo = new KComboBox ( writable, this );
00368 
00369     insertWidgetInternal( combo, index, id );
00370     combo->insertStringList (list);
00371     combo->setInsertionPolicy(policy);
00372     combo->setEnabled( enabled );
00373     if ( !tooltiptext.isEmpty() )
00374         QToolTip::add( combo, tooltiptext );
00375     if ( size > 0 )
00376         combo->setMinimumWidth( size );
00377     if (!tooltiptext.isNull())
00378         QToolTip::add( combo, tooltiptext );
00379 
00380     if ( signal && receiver && slot )
00381         connect ( combo, signal, receiver, slot );
00382     return index;
00383 }
00384 
00385 
00386 int KToolBar::insertCombo (const QString& text, int id, bool writable,
00387                             const char *signal, QObject *receiver,
00388                             const char *slot, bool enabled,
00389                             const QString& tooltiptext,
00390                             int size, int index,
00391                             QComboBox::Policy policy )
00392 {
00393     KComboBox *combo = new KComboBox ( writable, this );
00394     insertWidgetInternal( combo, index, id );
00395     combo->insertItem (text);
00396     combo->setInsertionPolicy(policy);
00397     combo->setEnabled( enabled );
00398     if ( !tooltiptext.isEmpty() )
00399         QToolTip::add( combo, tooltiptext );
00400     if ( size > 0 )
00401         combo->setMinimumWidth( size );
00402     if (!tooltiptext.isNull())
00403         QToolTip::add( combo, tooltiptext );
00404     connect (combo, signal, receiver, slot);
00405     return index;
00406 }
00407 
00408 int KToolBar::insertSeparator(int index, int id)
00409 {
00410     QWidget *w = new KToolBarSeparator( orientation(), false, this, "tool bar separator" );
00411     insertWidgetInternal( w, index, id );
00412     return index;
00413 }
00414 
00415 int KToolBar::insertLineSeparator(int index, int id)
00416 {
00417     QWidget *w = new KToolBarSeparator( orientation(), true, this, "tool bar separator" );
00418     insertWidgetInternal( w, index, id );
00419     return index;
00420 }
00421 
00422 
00423 int KToolBar::insertWidget(int id, int /*width*/, QWidget *widget, int index)
00424 {
00425     removeWidgetInternal( widget ); // in case we already have it ?
00426     insertWidgetInternal( widget, index, id );
00427     return index;
00428 }
00429 
00430 int KToolBar::insertAnimatedWidget(int id, QObject *receiver, const char *slot,
00431                                     const QString& icons, int index )
00432 {
00433     KAnimWidget *anim = new KAnimWidget( icons, d->m_iconSize, this );
00434     insertWidgetInternal( anim, index, id );
00435 
00436     if ( receiver )
00437         connect( anim, SIGNAL(clicked()), receiver, slot);
00438 
00439     return index;
00440 }
00441 
00442 KAnimWidget *KToolBar::animatedWidget( int id )
00443 {
00444     Id2WidgetMap::Iterator it = id2widget.find( id );
00445     if ( it == id2widget.end() )
00446         return 0;
00447     KAnimWidget *aw = dynamic_cast<KAnimWidget *>(*it);
00448     if ( aw )
00449         return aw;
00450     QObjectList *l = queryList( "KAnimWidget" );
00451     if ( !l || !l->first() ) {
00452         delete l;
00453         return 0;
00454     }
00455 
00456     for ( QObject *o = l->first(); o; o = l->next() ) {
00457         KAnimWidget *aw = dynamic_cast<KAnimWidget *>(o);
00458         if ( aw )
00459         {
00460             delete l;
00461             return aw;
00462         }
00463     }
00464 
00465     delete l;
00466     return 0;
00467 }
00468 
00469 
00470 void KToolBar::addConnection (int id, const char *signal,
00471                                const QObject *receiver, const char *slot)
00472 {
00473     Id2WidgetMap::Iterator it = id2widget.find( id );
00474     if ( it == id2widget.end() )
00475         return;
00476     if ( (*it) )
00477         connect( (*it), signal, receiver, slot );
00478 }
00479 
00480 void KToolBar::setItemEnabled( int id, bool enabled )
00481 {
00482     Id2WidgetMap::Iterator it = id2widget.find( id );
00483     if ( it == id2widget.end() )
00484         return;
00485     if ( (*it) )
00486         (*it)->setEnabled( enabled );
00487 }
00488 
00489 
00490 void KToolBar::setButtonPixmap( int id, const QPixmap& _pixmap )
00491 {
00492     Id2WidgetMap::Iterator it = id2widget.find( id );
00493     if ( it == id2widget.end() )
00494         return;
00495     KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
00496     if ( button )
00497         button->setPixmap( _pixmap );
00498 }
00499 
00500 
00501 void KToolBar::setButtonIcon( int id, const QString& _icon )
00502 {
00503     Id2WidgetMap::Iterator it = id2widget.find( id );
00504     if ( it == id2widget.end() )
00505         return;
00506     KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
00507     if ( button )
00508         button->setIcon( _icon );
00509 }
00510 
00511 void KToolBar::setButtonIconSet( int id, const QIconSet& iconset )
00512 {
00513     Id2WidgetMap::Iterator it = id2widget.find( id );
00514     if ( it == id2widget.end() )
00515         return;
00516     KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
00517     if ( button )
00518         button->setIconSet( iconset );
00519 }
00520 
00521 
00522 void KToolBar::setDelayedPopup (int id , QPopupMenu *_popup, bool toggle )
00523 {
00524     Id2WidgetMap::Iterator it = id2widget.find( id );
00525     if ( it == id2widget.end() )
00526         return;
00527     KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
00528     if ( button )
00529         button->setDelayedPopup( _popup, toggle );
00530 }
00531 
00532 
00533 void KToolBar::setAutoRepeat (int id, bool flag)
00534 {
00535     Id2WidgetMap::Iterator it = id2widget.find( id );
00536     if ( it == id2widget.end() )
00537         return;
00538     KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
00539     if ( button )
00540         button->setAutoRepeat( flag );
00541 }
00542 
00543 
00544 void KToolBar::setToggle (int id, bool flag )
00545 {
00546     Id2WidgetMap::Iterator it = id2widget.find( id );
00547     if ( it == id2widget.end() )
00548         return;
00549     KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
00550     if ( button )
00551         button->setToggle( flag );
00552 }
00553 
00554 
00555 void KToolBar::toggleButton (int id)
00556 {
00557     Id2WidgetMap::Iterator it = id2widget.find( id );
00558     if ( it == id2widget.end() )
00559         return;
00560     KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
00561     if ( button )
00562         button->toggle();
00563 }
00564 
00565 
00566 void KToolBar::setButton (int id, bool flag)
00567 {
00568     Id2WidgetMap::Iterator it = id2widget.find( id );
00569     if ( it == id2widget.end() )
00570         return;
00571     KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
00572     if ( button )
00573         button->on( flag );
00574 }
00575 
00576 
00577 bool KToolBar::isButtonOn (int id) const
00578 {
00579     Id2WidgetMap::ConstIterator it = id2widget.find( id );
00580     if ( it == id2widget.end() )
00581         return false;
00582     KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
00583     return button ? button->isOn() : false;
00584 }
00585 
00586 
00587 void KToolBar::setLinedText (int id, const QString& text)
00588 {
00589     Id2WidgetMap::Iterator it = id2widget.find( id );
00590     if ( it == id2widget.end() )
00591         return;
00592     QLineEdit * lineEdit = dynamic_cast<QLineEdit *>( *it );
00593     if ( lineEdit )
00594         lineEdit->setText( text );
00595 }
00596 
00597 
00598 QString KToolBar::getLinedText (int id) const
00599 {
00600     Id2WidgetMap::ConstIterator it = id2widget.find( id );
00601     if ( it == id2widget.end() )
00602         return QString::null;
00603     QLineEdit * lineEdit = dynamic_cast<QLineEdit *>( *it );
00604     return lineEdit ? lineEdit->text() : QString::null;
00605 }
00606 
00607 
00608 void KToolBar::insertComboItem (int id, const QString& text, int index)
00609 {
00610     Id2WidgetMap::Iterator it = id2widget.find( id );
00611     if ( it == id2widget.end() )
00612         return;
00613     QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
00614     if (comboBox)
00615         comboBox->insertItem( text, index );
00616 }
00617 
00618 void KToolBar::insertComboList (int id, const QStringList &list, int index)
00619 {
00620     Id2WidgetMap::Iterator it = id2widget.find( id );
00621     if ( it == id2widget.end() )
00622         return;
00623     QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
00624     if (comboBox)
00625         comboBox->insertStringList( list, index );
00626 }
00627 
00628 
00629 void KToolBar::removeComboItem (int id, int index)
00630 {
00631     Id2WidgetMap::Iterator it = id2widget.find( id );
00632     if ( it == id2widget.end() )
00633         return;
00634     QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
00635     if (comboBox)
00636         comboBox->removeItem( index );
00637 }
00638 
00639 
00640 void KToolBar::setCurrentComboItem (int id, int index)
00641 {
00642     Id2WidgetMap::Iterator it = id2widget.find( id );
00643     if ( it == id2widget.end() )
00644         return;
00645     QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
00646     if (comboBox)
00647         comboBox->setCurrentItem( index );
00648 }
00649 
00650 
00651 void KToolBar::changeComboItem  (int id, const QString& text, int index)
00652 {
00653     Id2WidgetMap::Iterator it = id2widget.find( id );
00654     if ( it == id2widget.end() )
00655         return;
00656     QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
00657     if (comboBox)
00658         comboBox->changeItem( text, index );
00659 }
00660 
00661 
00662 void KToolBar::clearCombo (int id)
00663 {
00664     Id2WidgetMap::Iterator it = id2widget.find( id );
00665     if ( it == id2widget.end() )
00666         return;
00667     QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
00668     if (comboBox)
00669         comboBox->clear();
00670 }
00671 
00672 
00673 QString KToolBar::getComboItem (int id, int index) const
00674 {
00675     Id2WidgetMap::ConstIterator it = id2widget.find( id );
00676     if ( it == id2widget.end() )
00677         return QString::null;
00678     QComboBox * comboBox = dynamic_cast<QComboBox *>( *it );
00679     return comboBox ? comboBox->text( index ) : QString::null;
00680 }
00681 
00682 
00683 KComboBox * KToolBar::getCombo(int id)
00684 {
00685     Id2WidgetMap::Iterator it = id2widget.find( id );
00686     if ( it == id2widget.end() )
00687         return 0;
00688     return dynamic_cast<KComboBox *>( *it );
00689 }
00690 
00691 
00692 KLineEdit * KToolBar::getLined (int id)
00693 {
00694     Id2WidgetMap::Iterator it = id2widget.find( id );
00695     if ( it == id2widget.end() )
00696         return 0;
00697     return dynamic_cast<KLineEdit *>( *it );
00698 }
00699 
00700 
00701 KToolBarButton * KToolBar::getButton (int id)
00702 {
00703     Id2WidgetMap::Iterator it = id2widget.find( id );
00704     if ( it == id2widget.end() )
00705         return 0;
00706     return dynamic_cast<KToolBarButton *>( *it );
00707 }
00708 
00709 
00710 void KToolBar::alignItemRight (int id, bool right )
00711 {
00712     Id2WidgetMap::Iterator it = id2widget.find( id );
00713     if ( it == id2widget.end() )
00714         return;
00715     if ( rightAligned && !right && (*it) == rightAligned )
00716         rightAligned = 0;
00717     if ( (*it) && right )
00718         rightAligned = (*it);
00719 }
00720 
00721 
00722 QWidget *KToolBar::getWidget (int id)
00723 {
00724     Id2WidgetMap::Iterator it = id2widget.find( id );
00725     return ( it == id2widget.end() ) ? 0 : (*it);
00726 }
00727 
00728 
00729 void KToolBar::setItemAutoSized (int id, bool yes )
00730 {
00731     QWidget *w = getWidget(id);
00732     if ( w && yes )
00733         setStretchableWidget( w );
00734 }
00735 
00736 
00737 void KToolBar::clear ()
00738 {
00739     QToolBar::clear();
00740     widget2id.clear();
00741     id2widget.clear();
00742 }
00743 
00744 
00745 void KToolBar::removeItem(int id)
00746 {
00747     Id2WidgetMap::Iterator it = id2widget.find( id );
00748     if ( it == id2widget.end() )
00749     {
00750         kdDebug(220) << name() << " KToolBar::removeItem item " << id << " not found" << endl;
00751         return;
00752     }
00753     QWidget * w = (*it);
00754     id2widget.remove( id );
00755     widget2id.remove( w );
00756     widgets.removeRef( w );
00757     delete w;
00758 }
00759 
00760 
00761 void KToolBar::removeItemDelayed(int id)
00762 {
00763     Id2WidgetMap::Iterator it = id2widget.find( id );
00764     if ( it == id2widget.end() )
00765     {
00766         kdDebug(220) << name() << " KToolBar::removeItem item " << id << " not found" << endl;
00767         return;
00768     }
00769     QWidget * w = (*it);
00770     id2widget.remove( id );
00771     widget2id.remove( w );
00772     widgets.removeRef( w );
00773 
00774     w->blockSignals(true);
00775     d->idleButtons.append(w);
00776     layoutTimer->start( 50, true );
00777 }
00778 
00779 
00780 void KToolBar::hideItem (int id)
00781 {
00782     QWidget *w = getWidget(id);
00783     if ( w )
00784         w->hide();
00785 }
00786 
00787 
00788 void KToolBar::showItem (int id)
00789 {
00790     QWidget *w = getWidget(id);
00791     if ( w )
00792         w->show();
00793 }
00794 
00795 
00796 int KToolBar::itemIndex (int id)
00797 {
00798     QWidget *w = getWidget(id);
00799     return w ? widgets.findRef(w) : -1;
00800 }
00801 
00802 int KToolBar::idAt (int index)
00803 {
00804     QWidget *w = widgets.at(index);
00805     return widget2id[w];
00806 }
00807 
00808 void KToolBar::setFullSize(bool flag )
00809 {
00810     setHorizontalStretchable( flag );
00811     setVerticalStretchable( flag );
00812 }
00813 
00814 
00815 bool KToolBar::fullSize() const
00816 {
00817     return isHorizontalStretchable() || isVerticalStretchable();
00818 }
00819 
00820 
00821 void KToolBar::enableMoving(bool flag )
00822 {
00823     setMovingEnabled(flag);
00824 }
00825 
00826 
00827 void KToolBar::setBarPos (BarPosition bpos)
00828 {
00829     if ( !mainWindow() )
00830         return;
00831     mainWindow()->moveDockWindow( this, (Dock)bpos );
00832     //kdDebug(220) << name() << " setBarPos dockWindowIndex=" << dockWindowIndex() << endl;
00833 }
00834 
00835 
00836 KToolBar::BarPosition KToolBar::barPos() const
00837 {
00838     if ( !this->mainWindow() )
00839         return KToolBar::Top;
00840     Dock dock;
00841     int dm1, dm2;
00842     bool dm3;
00843     this->mainWindow()->getLocation( (QToolBar*)this, dock, dm1, dm3, dm2 );
00844     if ( dock == DockUnmanaged ) {
00845         return (KToolBar::BarPosition)DockTop;
00846     }
00847     return (BarPosition)dock;
00848 }
00849 
00850 
00851 bool KToolBar::enable(BarStatus stat)
00852 {
00853     bool mystat = isVisible();
00854 
00855     if ( (stat == Toggle && mystat) || stat == Hide )
00856         hide();
00857     else
00858         show();
00859 
00860     return isVisible() == mystat;
00861 }
00862 
00863 
00864 void KToolBar::setMaxHeight ( int h )
00865 {
00866     setMaximumHeight( h );
00867 }
00868 
00869 int KToolBar::maxHeight()
00870 {
00871     return maximumHeight();
00872 }
00873 
00874 
00875 void KToolBar::setMaxWidth (int dw)
00876 {
00877     setMaximumWidth( dw );
00878 }
00879 
00880 
00881 int KToolBar::maxWidth()
00882 {
00883     return maximumWidth();
00884 }
00885 
00886 
00887 void KToolBar::setTitle (const QString& _title)
00888 {
00889     setLabel( _title );
00890 }
00891 
00892 
00893 void KToolBar::enableFloating (bool )
00894 {
00895 }
00896 
00897 
00898 void KToolBar::setIconText(IconText it)
00899 {
00900     setIconText( it, true );
00901 }
00902 
00903 
00904 void KToolBar::setIconText(IconText icontext, bool update)
00905 {
00906     bool doUpdate=false;
00907 
00908     if (icontext != d->m_iconText) {
00909         d->m_iconText = icontext;
00910         doUpdate=true;
00911         //kdDebug(220) << name() << "  icontext has changed, doUpdate=true" << endl;
00912     }
00913     else {
00914         //kdDebug(220) << name() << "  icontext hasn't changed, doUpdate=false" << endl;
00915     }
00916 
00917     if (update == false)
00918         return;
00919 
00920     if (doUpdate)
00921         emit modechange(); // tell buttons what happened
00922 
00923     // ugly hack to force a QMainWindow::triggerLayout( true )
00924     QMainWindow *mw = mainWindow();
00925     if ( mw ) {
00926         mw->setUpdatesEnabled( false );
00927         mw->setToolBarsMovable( !mw->toolBarsMovable() );
00928         mw->setToolBarsMovable( !mw->toolBarsMovable() );
00929         mw->setUpdatesEnabled( true );
00930     }
00931 }
00932 
00933 
00934 KToolBar::IconText KToolBar::iconText() const
00935 {
00936     return d->m_iconText;
00937 }
00938 
00939 
00940 void KToolBar::setIconSize(int size)
00941 {
00942     setIconSize( size, true );
00943 }
00944 
00945 void KToolBar::setIconSize(int size, bool update)
00946 {
00947     bool doUpdate=false;
00948 
00949     if ( size != d->m_iconSize ) {
00950             d->m_iconSize = size;
00951             doUpdate=true;
00952     }
00953 
00954     if (update == false)
00955         return;
00956 
00957     if (doUpdate)
00958         emit modechange(); // tell buttons what happened
00959 
00960     // ugly hack to force a QMainWindow::triggerLayout( true )
00961     if ( mainWindow() ) {
00962         QMainWindow *mw = mainWindow();
00963         mw->setUpdatesEnabled( false );
00964         mw->setToolBarsMovable( !mw->toolBarsMovable() );
00965         mw->setToolBarsMovable( !mw->toolBarsMovable() );
00966         mw->setUpdatesEnabled( true );
00967     }
00968 }
00969 
00970 
00971 int KToolBar::iconSize() const
00972 {
00973     if ( !d->m_iconSize ) // default value?
00974     {
00975          if (!::qstrcmp(QObject::name(), "mainToolBar"))
00976              return KGlobal::iconLoader()->currentSize(KIcon::MainToolbar);
00977          else
00978              return KGlobal::iconLoader()->currentSize(KIcon::Toolbar);
00979     }
00980     return d->m_iconSize;
00981 }
00982 
00983 
00984 void KToolBar::setEnableContextMenu(bool enable )
00985 {
00986     d->m_enableContext = enable;
00987 }
00988 
00989 
00990 bool KToolBar::contextMenuEnabled() const
00991 {
00992     return d->m_enableContext;
00993 }
00994 
00995 
00996 void KToolBar::setItemNoStyle(int id, bool no_style )
00997 {
00998     Id2WidgetMap::Iterator it = id2widget.find( id );
00999     if ( it == id2widget.end() )
01000         return;
01001     KToolBarButton * button = dynamic_cast<KToolBarButton *>( *it );
01002     if (button)
01003         button->setNoStyle( no_style );
01004 }
01005 
01006 
01007 void KToolBar::setFlat (bool flag)
01008 {
01009     if ( !mainWindow() )
01010         return;
01011     if ( flag )
01012         mainWindow()->moveDockWindow( this, DockMinimized );
01013     else
01014         mainWindow()->moveDockWindow( this, DockTop );
01015     // And remember to save the new look later
01016     KMainWindow *kmw = dynamic_cast<KMainWindow *>(mainWindow());
01017     if ( kmw )
01018         kmw->setSettingsDirty();
01019 }
01020 
01021 
01022 int KToolBar::count() const
01023 {
01024     return id2widget.count();
01025 }
01026 
01027 
01028 void KToolBar::saveState()
01029 {
01030     // first, try to save to the xml file
01031     if ( d->m_xmlguiClient && !d->m_xmlguiClient->xmlFile().isEmpty() ) {
01032         //kdDebug(220) << name() << " saveState: saving to " << d->m_xmlguiClient->xmlFile() << endl;
01033         // go down one level to get to the right tags
01034         QDomElement elem = d->m_xmlguiClient->domDocument().documentElement().toElement();
01035         elem = elem.firstChild().toElement();
01036         QString barname(!::qstrcmp(name(), "unnamed") ? "mainToolBar" : name());
01037         QDomElement current;
01038         // now try to find our toolbar
01039         d->modified = false;
01040         for( ; !elem.isNull(); elem = elem.nextSibling().toElement() ) {
01041             current = elem;
01042 
01043             if ( current.tagName().lower() != "toolbar" )
01044                 continue;
01045 
01046             QString curname(current.attribute( "name" ));
01047 
01048             if ( curname == barname ) {
01049                 saveState( current );
01050                 break;
01051             }
01052         }
01053         // if we didn't make changes, then just return
01054         if ( !d->modified )
01055             return;
01056 
01057         // now we load in the (non-merged) local file
01058         QString local_xml(KXMLGUIFactory::readConfigFile(d->m_xmlguiClient->xmlFile(), true, d->m_xmlguiClient->instance()));
01059         QDomDocument local;
01060         local.setContent(local_xml);
01061 
01062         // make sure we don't append if this toolbar already exists locally
01063         bool just_append = true;
01064         elem = local.documentElement().toElement();
01065         KXMLGUIFactory::removeDOMComments( elem );
01066         elem = elem.firstChild().toElement();
01067         for( ; !elem.isNull(); elem = elem.nextSibling().toElement() ) {
01068             if ( elem.tagName().lower() != "toolbar" )
01069                 continue;
01070 
01071             QString curname(elem.attribute( "name" ));
01072 
01073             if ( curname == barname ) {
01074                 just_append = false;
01075                 local.documentElement().replaceChild( current, elem );
01076                 break;
01077             }
01078         }
01079 
01080         if (just_append)
01081             local.documentElement().appendChild( current );
01082 
01083         KXMLGUIFactory::saveConfigFile(local, d->m_xmlguiClient->localXMLFile(), d->m_xmlguiClient->instance() );
01084 
01085         return;
01086     }
01087 
01088     // if that didn't work, we save to the config file
01089     KConfig *config = KGlobal::config();
01090     saveSettings(config, QString::null);
01091     config->sync();
01092 }
01093 
01094 QString KToolBar::settingsGroup() const
01095 {
01096     QString configGroup;
01097     if (!::qstrcmp(name(), "unnamed") || !::qstrcmp(name(), "mainToolBar"))
01098         configGroup = "Toolbar style";
01099     else
01100         configGroup = QString(name()) + " Toolbar style";
01101     if ( this->mainWindow() )
01102     {
01103         configGroup.prepend(" ");
01104         configGroup.prepend( this->mainWindow()->name() );
01105     }
01106     return configGroup;
01107 }
01108 
01109 void KToolBar::saveSettings(KConfig *config, const QString &_configGroup)
01110 {
01111     QString configGroup = _configGroup;
01112     if (configGroup.isEmpty())
01113         configGroup = settingsGroup();
01114     //kdDebug(220) << name() << " saveSettings() group=" << _configGroup << " -> " << configGroup << endl;
01115 
01116     QString position, icontext;
01117     int index;
01118     getAttributes( position, icontext, index );
01119 
01120     //kdDebug(220) << name() << "                position=" << position << " index=" << index << " offset=" << offset() << " newLine=" << newLine() << endl;
01121 
01122     KConfigGroupSaver saver(config, configGroup);
01123 
01124     if(!config->hasDefault("Position") && position == d->PositionDefault )
01125       config->revertToDefault("Position");
01126     else
01127       config->writeEntry("Position", position);
01128 
01129     //kdDebug(220) << name() << "                icontext=" << icontext << " hasDefault:" << config->hasDefault( "IconText" ) << " d->IconTextDefault=" << d->IconTextDefault << endl;
01130 
01131     if(d->m_honorStyle && icontext == d->IconTextDefault && !config->hasDefault("IconText") )
01132     {
01133       //kdDebug(220) << name() << "                reverting icontext to default" << endl;
01134       config->revertToDefault("IconText");
01135     }
01136     else
01137     {
01138       //kdDebug(220) << name() << "                writing icontext " << icontext << endl;
01139       config->writeEntry("IconText", icontext);
01140     }
01141 
01142     if(!config->hasDefault("IconSize") && iconSize() == d->IconSizeDefault )
01143       config->revertToDefault("IconSize");
01144     else
01145       config->writeEntry("IconSize", iconSize());
01146 
01147     if(!config->hasDefault("Hidden") && isHidden() == d->HiddenDefault )
01148       config->revertToDefault("Hidden");
01149     else
01150       config->writeEntry("Hidden", isHidden());
01151 
01152     // Note that index, unlike the other settings, depends on the other toolbars
01153     // So on the first run with a clean local config file, even the usual
01154     // hasDefault/==IndexDefault test would save the toolbar indexes
01155     // (IndexDefault was 0, whereas index is the real index in the GUI)
01156     //
01157     // Saving the whole set of indexes is necessary though. When moving only
01158     // one toolbar, if we only saved the changed indexes, the toolbars wouldn't
01159     // reappear at the same position the next time.
01160     // The whole set of indexes has to be saved.
01161     //kdDebug(220) << name() << "                writing index " << index << endl;
01162     config->writeEntry("Index", index);
01163 
01164     if(!config->hasDefault("Offset") && offset() == d->OffsetDefault )
01165       config->revertToDefault("Offset");
01166     else
01167       config->writeEntry("Offset", offset());
01168 
01169     if(!config->hasDefault("NewLine") && newLine() == d->NewLineDefault )
01170       config->revertToDefault("NewLine");
01171     else
01172       config->writeEntry("NewLine", newLine());
01173 }
01174 
01175 
01176 void KToolBar::setXMLGUIClient( KXMLGUIClient *client )
01177 {
01178     d->m_xmlguiClient = client;
01179 }
01180 
01181 void KToolBar::setText( const QString & txt )
01182 {
01183     setLabel( txt + " (" + kapp->caption() + ") " );
01184 }
01185 
01186 
01187 QString KToolBar::text() const
01188 {
01189     return label();
01190 }
01191 
01192 
01193 void KToolBar::doConnections( KToolBarButton *button )
01194 {
01195     connect(button, SIGNAL(clicked(int)), this, SIGNAL( clicked( int ) ) );
01196     connect(button, SIGNAL(doubleClicked(int)), this, SIGNAL( doubleClicked( int ) ) );
01197     connect(button, SIGNAL(released(int)), this, SIGNAL( released( int ) ) );
01198     connect(button, SIGNAL(pressed(int)), this, SIGNAL( pressed( int ) ) );
01199     connect(button, SIGNAL(toggled(int)), this, SIGNAL( toggled( int ) ) );
01200     connect(button, SIGNAL(highlighted(int, bool)), this, SIGNAL( highlighted( int, bool ) ) );
01201 }
01202 
01203 void KToolBar::mousePressEvent ( QMouseEvent *m )
01204 {
01205     if ( !mainWindow() )
01206         return;
01207     QMainWindow *mw = mainWindow();
01208     if ( mw->toolBarsMovable() && d->m_enableContext ) {
01209         if ( m->button() == RightButton ) {
01210             int i = contextMenu()->exec( m->globalPos(), 0 );
01211             switch ( i ) {
01212             case -1:
01213                 return; // popup canceled
01214             case CONTEXT_LEFT:
01215                 mw->moveDockWindow( this, DockLeft );
01216                 break;
01217             case CONTEXT_RIGHT:
01218                 mw->moveDockWindow( this, DockRight );
01219                 break;
01220             case CONTEXT_TOP:
01221                 mw->moveDockWindow( this, DockTop );
01222                 break;
01223             case CONTEXT_BOTTOM:
01224                 mw->moveDockWindow( this, DockBottom );
01225                 break;
01226             case CONTEXT_FLOAT:
01227                 break;
01228             case CONTEXT_FLAT:
01229                 mw->moveDockWindow( this, DockMinimized );
01230                 break;
01231             case CONTEXT_ICONS:
01232                 setIconText( IconOnly );
01233                 break;
01234             case CONTEXT_TEXTRIGHT:
01235                 setIconText( IconTextRight );
01236                 break;
01237             case CONTEXT_TEXT:
01238                 setIconText( TextOnly );
01239                 break;
01240             case CONTEXT_TEXTUNDER:
01241                 setIconText( IconTextBottom );
01242                 break;
01243             default:
01244                 if ( i >= CONTEXT_ICONSIZES )
01245                     setIconSize( i - CONTEXT_ICONSIZES );
01246                 else
01247                     return; // assume this was an action handled elsewhere, no need for setSettingsDirty()
01248             }
01249             KMainWindow *kmw = dynamic_cast<KMainWindow *>(mw);
01250             if ( kmw )
01251                 kmw->setSettingsDirty();
01252         }
01253     }
01254 }
01255 
01256 
01257 void KToolBar::rebuildLayout()
01258 {
01259     for(QWidget *w=d->idleButtons.first(); w; w=d->idleButtons.next())
01260        w->blockSignals(false);
01261     d->idleButtons.clear();
01262 
01263     layoutTimer->stop();
01264     QApplication::sendPostedEvents( this, QEvent::ChildInserted );
01265     QBoxLayout *l = boxLayout();
01266 
01267     // clear the old layout
01268     QLayoutIterator it = l->iterator();
01269     while ( it.current() )
01270         it.deleteCurrent();
01271 
01272     for ( QWidget *w = widgets.first(); w; w = widgets.next() ) {
01273         if ( w == rightAligned )
01274             continue;
01275         KToolBarSeparator *ktbs = dynamic_cast<KToolBarSeparator *>(w);
01276         if ( ktbs && !ktbs->showLine() ) {
01277             l->addSpacing( orientation() == Vertical ? w->sizeHint().height() : w->sizeHint().width() );
01278             w->hide();
01279             continue;
01280         }
01281         if ( dynamic_cast<QPopupMenu *>(w) ) // w is a QPopupMenu?
01282             continue;
01283         l->addWidget( w );
01284         w->show();
01285         if ((orientation() == Horizontal) && dynamic_cast<QLineEdit *>(w)) // w is QLineEdit ?
01286             l->addSpacing(2); // A little bit extra spacing behind it.
01287     }
01288     if ( rightAligned ) {
01289         l->addStretch();
01290         l->addWidget( rightAligned );
01291         rightAligned->show();
01292     }
01293 
01294     if ( fullSize() ) {
01295         if ( !rightAligned )
01296             l->addStretch();
01297         if ( stretchableWidget )
01298             l->setStretchFactor( stretchableWidget, 10 );
01299     }
01300     l->invalidate();
01301     QApplication::postEvent( this, new QEvent( QEvent::LayoutHint ) );
01302 }
01303 
01304 void KToolBar::childEvent( QChildEvent *e )
01305 {
01306     if ( e->child()->isWidgetType() ) {
01307         QWidget * w = dynamic_cast<QWidget *>(e->child());
01308         if (!w || (::qstrcmp( "qt_dockwidget_internal", w->name()) == 0))
01309         {
01310            QToolBar::childEvent( e );
01311            return;
01312         }
01313         if ( e->type() == QEvent::ChildInserted ) {
01314             if ( !dynamic_cast<QPopupMenu *>(w)) { // e->child() is not a QPopupMenu
01315                 // prevent items that have been explicitly inserted by insert*() from
01316                 // being inserted again
01317                 if ( !widget2id.contains( w ) )
01318                 {
01319                     int dummy = -1;
01320                     insertWidgetInternal( w, dummy, -1 );
01321                 }
01322             }
01323         } else {
01324             removeWidgetInternal( w );
01325         }
01326         if ( isVisibleTo( 0 ) )
01327         {
01328             layoutTimer->start( 50, true );
01329             QBoxLayout *l = boxLayout();
01330 
01331             // clear the old layout so that we don't get unnecassery layout
01332             // changes till we have rebuild the thing
01333