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., 51 Franklin Street, Fifth Floor, 00023 Boston, MA 02110-1301, USA. 00024 */ 00025 00026 #include <config.h> 00027 00028 #ifdef KDE_USE_FINAL 00029 #undef Always 00030 #include <qdockwindow.h> 00031 #endif 00032 00033 #include <string.h> 00034 00035 #include <qpainter.h> 00036 #include <qtooltip.h> 00037 #include <qdrawutil.h> 00038 #include <qstring.h> 00039 #include <qrect.h> 00040 #include <qobjectlist.h> 00041 #include <qtimer.h> 00042 #include <qstyle.h> 00043 #include <qlayout.h> 00044 00045 #include <ktoolbar.h> 00046 #include <kmainwindow.h> 00047 #include <klineedit.h> 00048 #include <kseparator.h> 00049 #include <klocale.h> 00050 #include <kapplication.h> 00051 #include <kaction.h> 00052 #include <kstdaction.h> 00053 #include <kglobal.h> 00054 #include <kconfig.h> 00055 #include <kiconloader.h> 00056 #include <kcombobox.h> 00057 #include <kpopupmenu.h> 00058 #include <kanimwidget.h> 00059 #include <kedittoolbar.h> 00060 #include <kipc.h> 00061 #include <kwin.h> 00062 #include <kdebug.h> 00063 #include <ktoolbarbutton.h> 00064 00065 enum { 00066 CONTEXT_TOP = 0, 00067 CONTEXT_LEFT = 1, 00068 CONTEXT_RIGHT = 2, 00069 CONTEXT_BOTTOM = 3, 00070 CONTEXT_FLOAT = 4, 00071 CONTEXT_FLAT = 5, 00072 CONTEXT_ICONS = 6, 00073 CONTEXT_TEXT = 7, 00074 CONTEXT_TEXTRIGHT = 8, 00075 CONTEXT_TEXTUNDER = 9, 00076 CONTEXT_ICONSIZES = 50 // starting point for the icon size list, put everything else before 00077 }; 00078 00079 class KToolBarPrivate 00080 { 00081 public: 00082 KToolBarPrivate() { 00083 m_iconSize = 0; 00084 m_iconText = KToolBar::IconOnly; 00085 m_highlight = true; 00086 m_transparent = true; 00087 m_honorStyle = false; 00088 00089 m_enableContext = true; 00090 00091 m_xmlguiClient = 0; 00092 00093 oldPos = Qt::DockUnmanaged; 00094 00095 modified = m_isHorizontal = positioned = false; 00096 00097 IconSizeDefault = 0; 00098 IconTextDefault = "IconOnly"; 00099 00100 NewLineDefault = false; 00101 OffsetDefault = 0; 00102 PositionDefault = "Top"; 00103 HiddenDefault = false; 00104 idleButtons.setAutoDelete(true); 00105 } 00106 00107 int m_iconSize; 00108 KToolBar::IconText m_iconText; 00109 bool m_highlight : 1; 00110 bool m_transparent : 1; 00111 bool m_honorStyle : 1; 00112 bool m_isHorizontal : 1; 00113 bool m_enableContext : 1; 00114 bool modified : 1; 00115 bool positioned : 1; 00116 00117 QWidget *m_parent; 00118 00119 QMainWindow::ToolBarDock oldPos; 00120 00121 KXMLGUIClient *m_xmlguiClient; 00122 00123 struct ToolBarInfo 00124 { 00125 ToolBarInfo() : index( -1 ), offset( -1 ), newline( false ), dock( Qt::DockTop ) {} 00126 ToolBarInfo( Qt::Dock d, int i, bool n, int o ) : index( i ), offset( o ), newline( n ), dock( d ) {} 00127 int index, offset; 00128 bool newline; 00129 Qt::Dock dock; 00130 }; 00131 00132 ToolBarInfo toolBarInfo; 00133 QValueList<int> iconSizes; 00134 QTimer repaintTimer; 00135 00136 // Default Values. 00137 bool HiddenDefault; 00138 int IconSizeDefault; 00139 QString IconTextDefault; 00140 bool NewLineDefault; 00141 int OffsetDefault; 00142 QString PositionDefault; 00143 00144 QPtrList<QWidget> idleButtons; 00145 }; 00146 00147 KToolBarSeparator::KToolBarSeparator(Orientation o , bool l, QToolBar *parent, 00148 const char* name ) 00149 :QFrame( parent, name ), line( l ) 00150 { 00151 connect( parent, SIGNAL(orientationChanged(Orientation)), 00152 this, SLOT(setOrientation(Orientation)) ); 00153 setOrientation( o ); 00154 setBackgroundMode( parent->backgroundMode() ); 00155 setBackgroundOrigin( ParentOrigin ); 00156 } 00157 00158 void KToolBarSeparator::setOrientation( Orientation o ) 00159 { 00160 orient = o; 00161 setFrameStyle( NoFrame ); 00162 } 00163 00164 void KToolBarSeparator::drawContents( QPainter* p ) 00165 { 00166 if ( line ) { 00167 QStyle::SFlags flags = QStyle::Style_Default; 00168 00169 if ( orientation() == Horizontal ) 00170 flags = flags | QStyle::Style_Horizontal; 00171 00172 style().drawPrimitive(QStyle::PE_DockWindowSeparator, p, 00173 contentsRect(), colorGroup(), flags); 00174 } else { 00175 QFrame::drawContents(p); 00176 } 00177 } 00178 00179 void KToolBarSeparator::styleChange( QStyle& ) 00180 { 00181 setOrientation( orient ); 00182 } 00183 00184 QSize KToolBarSeparator::sizeHint() const 00185 { 00186 int dim = style().pixelMetric( QStyle::PM_DockWindowSeparatorExtent, this ); 00187 return orientation() == Vertical ? QSize( 0, dim ) : QSize( dim, 0 ); 00188 } 00189 00190 QSizePolicy KToolBarSeparator::sizePolicy() const 00191 { 00192 return QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ); 00193 } 00194 00195 KToolBar::KToolBar( QWidget *parent, const char *name, bool honorStyle, bool readConfig ) 00196 : QToolBar( QString::fromLatin1( name ), 00197 dynamic_cast<QMainWindow*>(parent), 00198 parent, false, 00199 name ? name : "mainToolBar") 00200 { 00201 init( readConfig, honorStyle ); 00202 } 00203 00204 KToolBar::KToolBar( QMainWindow *parentWindow, QMainWindow::ToolBarDock dock, bool newLine, const char *name, bool honorStyle, bool readConfig ) 00205 : QToolBar( QString::fromLatin1( name ), 00206 parentWindow, dock, newLine, 00207 name ? name : "mainToolBar") 00208 { 00209 init( readConfig, honorStyle ); 00210 } 00211 00212 KToolBar::KToolBar( QMainWindow *parentWindow, QWidget *dock, bool newLine, const char *name, bool honorStyle, bool readConfig ) 00213 : QToolBar( QString::fromLatin1( name ), 00214 parentWindow, dock, newLine, 00215 name ? name : "mainToolBar") 00216 { 00217 init( readConfig, honorStyle ); 00218 } 00219 00220 KToolBar::~KToolBar() 00221 { 00222 emit toolbarDestroyed(); 00223 delete d; 00224 } 00225 00226 void KToolBar::init( bool readConfig, bool honorStyle ) 00227 { 00228 d = new KToolBarPrivate; 00229 setFullSize( true ); 00230 d->m_honorStyle = honorStyle; 00231 context = 0; 00232 layoutTimer = new QTimer( this ); 00233 connect( layoutTimer, SIGNAL( timeout() ), 00234 this, SLOT( rebuildLayout() ) ); 00235 connect( &(d->repaintTimer), SIGNAL( timeout() ), 00236 this, SLOT( slotRepaint() ) ); 00237 00238 if ( kapp ) { // may be null when started inside designer 00239 connect(kapp, SIGNAL(toolbarAppearanceChanged(int)), this, SLOT(slotAppearanceChanged())); 00240 // request notification of changes in icon style 00241 kapp->addKipcEventMask(KIPC::IconChanged); 00242 connect(kapp, SIGNAL(iconChanged(int)), this, SLOT(slotIconChanged(int))); 00243 } 00244 00245 // finally, read in our configurable settings 00246 if ( readConfig ) 00247 slotReadConfig(); 00248 00249 if ( mainWindow() ) 00250 connect( mainWindow(), SIGNAL( toolBarPositionChanged( QToolBar * ) ), 00251 this, SLOT( toolBarPosChanged( QToolBar * ) ) ); 00252 00253 // Hack to make sure we recalculate our size when we dock. 00254 connect( this, SIGNAL(placeChanged(QDockWindow::Place)), SLOT(rebuildLayout()) ); 00255 } 00256 00257 int KToolBar::insertButton(const QString& icon, int id, bool enabled, 00258 const QString& text, int index, KInstance *_instance ) 00259 { 00260 KToolBarButton *button = new KToolBarButton( icon, id, this, 0, text, _instance ); 00261 00262 insertWidgetInternal( button, index, id ); 00263 button->setEnabled( enabled ); 00264 doConnections( button ); 00265 return index; 00266 } 00267 00268 00269 int KToolBar::insertButton(const QString& icon, int id, const char *signal, 00270 const QObject *receiver, const char *slot, 00271 bool enabled, const QString& text, int index, KInstance *_instance ) 00272 { 00273 KToolBarButton *button = new KToolBarButton( icon, id, this, 0, text, _instance); 00274 insertWidgetInternal( button, index, id ); 00275 button->setEnabled( enabled ); 00276 connect( button, signal, receiver, slot ); 00277 doConnections( button ); 00278 return index; 00279 } 00280 00281 00282 int KToolBar::insertButton(const QPixmap& pixmap, int id, bool enabled, 00283 const QString& text, int index ) 00284 { 00285 KToolBarButton *button = new KToolBarButton( pixmap, id, this, 0, text); 00286 insertWidgetInternal( button, index, id ); 00287 button->setEnabled( enabled ); 00288 doConnections( button ); 00289 return index; 00290 } 00291 00292 00293 int KToolBar::insertButton(const QPixmap& pixmap, int id, const char *signal, 00294 const QObject *receiver, const char *slot, 00295 bool enabled, const QString& text, 00296 int index ) 00297 { 00298 KToolBarButton *button = new KToolBarButton( pixmap, id, this, 0, text); 00299 insertWidgetInternal( button, index, id ); 00300 button->setEnabled( enabled ); 00301 connect( button, signal, receiver, slot ); 00302 doConnections( button ); 00303 return index; 00304 } 00305 00306 00307 int KToolBar::insertButton(const QString& icon, int id, QPopupMenu *popup, 00308 bool enabled, const QString &text, int index ) 00309 { 00310 KToolBarButton *button = new KToolBarButton( icon, id, this, 0, text ); 00311 insertWidgetInternal( button, index, id ); 00312 button->setEnabled( enabled ); 00313 button->setPopup( popup ); 00314 doConnections( button ); 00315 return index; 00316 } 00317 00318 00319 int KToolBar::insertButton(const QPixmap& pixmap, int id, QPopupMenu *popup, 00320 bool enabled, const QString &text, int index ) 00321 { 00322 KToolBarButton *button = new KToolBarButton( pixmap, id, this, 0, text ); 00323 insertWidgetInternal( button, index, id ); 00324 button->setEnabled( enabled ); 00325 button->setPopup( popup ); 00326 doConnections( button ); 00327 return index; 00328 } 00329 00330 00331 int KToolBar::insertLined (const QString& text, int id, 00332 const char *signal, 00333 const QObject *receiver, const char *slot, 00334 bool enabled , 00335 const QString& toolTipText, 00336 int size, int index ) 00337 { 00338 KLineEdit *lined = new KLineEdit ( this, 0 ); 00339 if ( !toolTipText.isEmpty() ) 00340 QToolTip::add( lined, toolTipText ); 00341 if ( size > 0 ) 00342 lined->setMinimumWidth( size ); 00343 insertWidgetInternal( lined, index, id ); 00344 connect( lined, signal, receiver, slot ); 00345 lined->setText(text); 00346 lined->setEnabled( enabled ); 00347 return index; 00348 } 00349 00350 int KToolBar::insertCombo (const QStringList &list, int id, bool writable, 00351 const char *signal, const QObject *receiver, 00352 const char *slot, bool enabled, 00353 const QString& tooltiptext, 00354 int size, int index, 00355 QComboBox::Policy policy ) 00356 { 00357 KComboBox *combo = new KComboBox ( writable, this ); 00358 00359 insertWidgetInternal( combo, index, id ); 00360 combo->insertStringList (list); 00361 combo->setInsertionPolicy(policy); 00362 combo->setEnabled( enabled ); 00363 if ( size > 0 ) 00364 combo->setMinimumWidth( size ); 00365 if (!tooltiptext.isNull()) 00366 QToolTip::add( combo, tooltiptext ); 00367 00368 if ( signal && receiver && slot ) 00369 connect ( combo, signal, receiver, slot ); 00370 return index; 00371 } 00372 00373 00374 int KToolBar::insertCombo (const QString& text, int id, bool writable, 00375 const char *signal, QObject *receiver, 00376 const char *slot, bool enabled, 00377 const QString& tooltiptext, 00378 int size, int index, 00379 QComboBox::Policy policy ) 00380 { 00381 KComboBox *combo = new KComboBox ( writable, this ); 00382 insertWidgetInternal( combo, index, id ); 00383 combo->insertItem (text); 00384 combo->setInsertionPolicy(policy); 00385 combo->setEnabled( enabled ); 00386 if ( size > 0 ) 00387 combo->setMinimumWidth( size ); 00388 if (!tooltiptext.isNull()) 00389 QToolTip::add( combo, tooltiptext ); 00390 connect (combo, signal, receiver, slot); 00391 return index; 00392 } 00393 00394 int KToolBar::insertSeparator(int index, int id) 00395 { 00396 QWidget *w = new KToolBarSeparator( orientation(), false, this, "tool bar separator" ); 00397 insertWidgetInternal( w, index, id ); 00398 return index; 00399 } 00400 00401 int KToolBar::insertLineSeparator(int index, int id) 00402 { 00403 QWidget *w = new KToolBarSeparator( orientation(), true, this, "tool bar separator" ); 00404 insertWidgetInternal( w, index, id ); 00405 return index; 00406 } 00407 00408 00409 int KToolBar::insertWidget(int id, int /*width*/, QWidget *widget, int index) 00410 { 00411 removeWidgetInternal( widget ); // in case we already have it ? 00412 insertWidgetInternal( widget, index, id ); 00413 return index; 00414 } 00415 00416 int KToolBar::insertAnimatedWidget(int id, QObject *receiver, const char *slot, 00417 const QString& icons, int index ) 00418 { 00419 KAnimWidget *anim = new KAnimWidget( icons, d->m_iconSize, this ); 00420 insertWidgetInternal( anim, index, id ); 00421 00422 if ( receiver ) 00423 connect( anim, SIGNAL(clicked()), receiver, slot); 00424 00425 return index; 00426 } 00427 00428 KAnimWidget *KToolBar::animatedWidget( int id ) 00429 { 00430 Id2WidgetMap::Iterator it = id2widget.find( id ); 00431 if ( it == id2widget.end() ) 00432 return 0; 00433 KAnimWidget *aw = dynamic_cast<KAnimWidget *>(*it); 00434 if ( aw ) 00435 return aw; 00436 QObjectList *l = queryList( "KAnimWidget" ); 00437 if ( !l || !l->first() ) { 00438 delete l; 00439 return 0; 00440 } 00441 00442 for ( QObject *o = l->first(); o; o = l->next() ) { 00443 KAnimWidget *aw = dynamic_cast<KAnimWidget *>(o); 00444 if ( aw ) 00445 { 00446 delete l; 00447 return aw; 00448 } 00449 } 00450 00451 delete l; 00452 return 0; 00453 } 00454 00455 00456 void KToolBar::addConnection (int id, const char *signal, 00457 const QObject *receiver, const char *slot) 00458 { 00459 QWidget* w = getWidget( id ); 00460 if ( w ) 00461 connect( w, signal, receiver, slot ); 00462 } 00463 00464 void KToolBar::setItemEnabled( int id, bool enabled ) 00465 { 00466 QWidget* w = getWidget( id ); 00467 if ( w ) 00468 w->setEnabled( enabled ); 00469 } 00470 00471 00472 void KToolBar::setButtonPixmap( int id, const QPixmap& _pixmap ) 00473 { 00474 KToolBarButton * button = getButton( id ); 00475 if ( button ) 00476 button->setPixmap( _pixmap ); 00477 } 00478 00479 00480 void KToolBar::setButtonIcon( int id, const QString& _icon ) 00481 { 00482 KToolBarButton * button = getButton( id ); 00483 if ( button ) 00484 button->setIcon( _icon ); 00485 } 00486 00487 void KToolBar::setButtonIconSet( int id, const QIconSet& iconset ) 00488 { 00489 KToolBarButton * button = getButton( id ); 00490 if ( button ) 00491 button->setIconSet( iconset ); 00492 } 00493 00494 00495 void KToolBar::setDelayedPopup (int id , QPopupMenu *_popup, bool toggle ) 00496 { 00497 KToolBarButton * button = getButton( id ); 00498 if ( button ) 00499 button->setDelayedPopup( _popup, toggle ); 00500 } 00501 00502 00503 void KToolBar::setAutoRepeat (int id, bool flag) 00504 { 00505 KToolBarButton * button = getButton( id ); 00506 if ( button ) 00507 button->setAutoRepeat( flag ); 00508 } 00509 00510 00511 void KToolBar::setToggle (int id, bool flag ) 00512 { 00513 KToolBarButton * button = getButton( id ); 00514 if ( button ) 00515 button->setToggle( flag ); 00516 } 00517 00518 00519 void KToolBar::toggleButton (int id) 00520 { 00521 KToolBarButton * button = getButton( id ); 00522 if ( button ) 00523 button->toggle(); 00524 } 00525 00526 00527 void KToolBar::setButton (int id, bool flag) 00528 { 00529 KToolBarButton * button = getButton( id ); 00530 if ( button ) 00531 button->on( flag ); 00532 } 00533 00534 00535 bool KToolBar::isButtonOn (int id) const 00536 { 00537 KToolBarButton * button = const_cast<KToolBar*>( this )->getButton( id ); 00538 return button ? button->isOn() : false; 00539 } 00540 00541 00542 void KToolBar::setLinedText (int id, const QString& text) 00543 { 00544 KLineEdit * lineEdit = getLined( id ); 00545 if ( lineEdit ) 00546 lineEdit->setText( text ); 00547 } 00548 00549 00550 QString KToolBar::getLinedText (int id) const 00551 { 00552 KLineEdit * lineEdit = const_cast<KToolBar*>( this )->getLined( id ); 00553 return lineEdit ? lineEdit->text() : QString::null; 00554 } 00555 00556 00557 void KToolBar::insertComboItem (int id, const QString& text, int index) 00558 { 00559 KComboBox * comboBox = getCombo( id ); 00560 if (comboBox) 00561 comboBox->insertItem( text, index ); 00562 } 00563 00564 void KToolBar::insertComboList (int id, const QStringList &list, int index) 00565 { 00566 KComboBox * comboBox = getCombo( id ); 00567 if (comboBox) 00568 comboBox->insertStringList( list, index ); 00569 } 00570 00571 00572 void KToolBar::removeComboItem (int id, int index) 00573 { 00574 KComboBox * comboBox = getCombo( id ); 00575 if (comboBox) 00576 comboBox->removeItem( index ); 00577 } 00578 00579 00580 void KToolBar::setCurrentComboItem (int id, int index) 00581 { 00582 KComboBox * comboBox = getCombo( id ); 00583 if (comboBox) 00584 comboBox->setCurrentItem( index ); 00585 } 00586 00587 00588 void KToolBar::changeComboItem (int id, const QString& text, int index) 00589 { 00590 KComboBox * comboBox = getCombo( id ); 00591 if (comboBox) 00592 comboBox->changeItem( text, index ); 00593 } 00594 00595 00596 void KToolBar::clearCombo (int id) 00597 { 00598 KComboBox * comboBox = getCombo( id ); 00599 if (comboBox) 00600 comboBox->clear(); 00601 } 00602 00603 00604 QString KToolBar::getComboItem (int id, int index) const 00605 { 00606 KComboBox * comboBox = const_cast<KToolBar*>( this )->getCombo( id ); 00607 return comboBox ? comboBox->text( index ) : QString::null; 00608 } 00609 00610 00611 KComboBox * KToolBar::getCombo(int id) 00612 { 00613 Id2WidgetMap::Iterator it = id2widget.find( id ); 00614 if ( it == id2widget.end() ) 00615 return 0; 00616 return dynamic_cast<KComboBox *>( *it ); 00617 } 00618 00619 00620 KLineEdit * KToolBar::getLined (int id) 00621 { 00622 Id2WidgetMap::Iterator it = id2widget.find( id ); 00623 if ( it == id2widget.end() ) 00624 return 0; 00625 return dynamic_cast<KLineEdit *>( *it ); 00626 } 00627 00628 00629 KToolBarButton * KToolBar::getButton (int id) 00630 { 00631 Id2WidgetMap::Iterator it = id2widget.find( id ); 00632 if ( it == id2widget.end() ) 00633 return 0; 00634 return dynamic_cast<KToolBarButton *>( *it ); 00635 } 00636 00637 00638 void KToolBar::alignItemRight (int id, bool right ) 00639 { 00640 Id2WidgetMap::Iterator it = id2widget.find( id ); 00641 if ( it == id2widget.end() ) 00642 return; 00643 if ( rightAligned && !right && (*it) == rightAligned ) 00644 rightAligned = 0; 00645 if ( (*it) && right ) 00646 rightAligned = (*it); 00647 } 00648 00649 00650 QWidget *KToolBar::getWidget (int id) 00651 { 00652 Id2WidgetMap::Iterator it = id2widget.find( id ); 00653 return ( it == id2widget.end() ) ? 0 : (*it); 00654 } 00655 00656 00657 void KToolBar::setItemAutoSized (int id, bool yes ) 00658 { 00659 QWidget *w = getWidget(id); 00660 if ( w && yes ) 00661 setStretchableWidget( w ); 00662 } 00663 00664 00665 void KToolBar::clear () 00666 { 00667 /* Delete any idle buttons, so QToolBar doesn't delete them itself, making a mess */ 00668 for(QWidget *w=d->idleButtons.first(); w; w=d->idleButtons.next()) 00669 w->blockSignals(false); 00670 d->idleButtons.clear(); 00671 00672 QToolBar::clear(); 00673 widget2id.clear(); 00674 id2widget.clear(); 00675 } 00676 00677 00678 void KToolBar::removeItem(int id) 00679 { 00680 Id2WidgetMap::Iterator it = id2widget.find( id ); 00681 if ( it == id2widget.end() ) 00682 { 00683 kdDebug(220) << name() << " KToolBar::removeItem item " << id << " not found" << endl; 00684 return; 00685 } 00686 QWidget * w = (*it); 00687 id2widget.remove( id ); 00688 widget2id.remove( w ); 00689 widgets.removeRef( w ); 00690 delete w; 00691 } 00692 00693 00694 void KToolBar::removeItemDelayed(int id) 00695 { 00696 Id2WidgetMap::Iterator it = id2widget.find( id ); 00697 if ( it == id2widget.end() ) 00698 { 00699 kdDebug(220) << name() << " KToolBar::removeItem item " << id << " not found" << endl; 00700 return; 00701 } 00702 QWidget * w = (*it); 00703 id2widget.remove( id ); 00704 widget2id.remove( w ); 00705 widgets.removeRef( w ); 00706 00707 w->blockSignals(true); 00708 d->idleButtons.append(w); 00709 layoutTimer->start( 50, true ); 00710 } 00711 00712 00713 void KToolBar::hideItem (int id) 00714 { 00715 QWidget *w = getWidget(id); 00716 if ( w ) 00717 w->hide(); 00718 } 00719 00720 00721 void KToolBar::showItem (int id) 00722 { 00723 QWidget *w = getWidget(id); 00724 if ( w ) 00725 w->show(); 00726 } 00727 00728 00729 int KToolBar::itemIndex (int id) 00730 { 00731 QWidget *w = getWidget(id); 00732 return w ? widgets.findRef(w) : -1; 00733 } 00734 00735 int KToolBar::idAt (int index) 00736 { 00737 QWidget *w = widgets.at(index); 00738 return widget2id[w]; 00739 } 00740 00741 void KToolBar::setFullSize(bool flag ) 00742 { 00743 setHorizontalStretchable( flag ); 00744 setVerticalStretchable( flag ); 00745 } 00746 00747 00748 bool KToolBar::fullSize() const 00749 { 00750 return isHorizontalStretchable() || isVerticalStretchable(); 00751 } 00752 00753 00754 void KToolBar::enableMoving(bool flag ) 00755 { 00756 setMovingEnabled(flag); 00757 } 00758 00759 00760 void KToolBar::setBarPos (BarPosition bpos) 00761 { 00762 if ( !mainWindow() ) 00763 return; 00764 mainWindow()->moveDockWindow( this, (Dock)bpos ); 00765 //kdDebug(220) << name() << " setBarPos dockWindowIndex=" << dockWindowIndex() << endl; 00766 } 00767 00768 00769 KToolBar::BarPosition KToolBar::barPos() const 00770 { 00771 if ( !this->mainWindow() ) 00772 return place() == QDockWindow::InDock ? KToolBar::Top : KToolBar::Floating; 00773 Dock dock; 00774 int dm1, dm2; 00775 bool dm3; 00776 this->mainWindow()->getLocation( (QToolBar*)this, dock, dm1, dm3, dm2 ); 00777 if ( dock == DockUnmanaged ) { 00778 return (KToolBar::BarPosition)DockTop; 00779 } 00780 return (BarPosition)dock; 00781 } 00782 00783 00784 bool KToolBar::enable(BarStatus stat) 00785 { 00786 bool mystat = isVisible(); 00787 00788 if ( (stat == Toggle && mystat) || stat == Hide ) 00789 hide(); 00790 else 00791 show(); 00792 00793 return isVisible() == mystat; 00794 } 00795 00796 00797 void KToolBar::setMaxHeight ( int h ) 00798 { 00799 setMaximumHeight( h ); 00800 } 00801 00802 int KToolBar::maxHeight() 00803 { 00804 return maximumHeight(); 00805 } 00806 00807 00808 void KToolBar::setMaxWidth (int dw) 00809 { 00810 setMaximumWidth( dw ); 00811 } 00812 00813 00814 int KToolBar::maxWidth() 00815 { 00816 return maximumWidth(); 00817 } 00818 00819 00820 void KToolBar::setTitle (const QString& _title) 00821 { 00822 setLabel( _title ); 00823 } 00824 00825 00826 void KToolBar::enableFloating (bool ) 00827 { 00828 } 00829 00830 00831 void KToolBar::setIconText(IconText it) 00832 { 00833 setIconText( it, true ); 00834 } 00835 00836 00837 void KToolBar::setIconText(IconText icontext, bool update) 00838 { 00839 bool doUpdate=false; 00840 00841 if (icontext != d->m_iconText) { 00842 d->m_iconText = icontext; 00843 doUpdate=true; 00844 //kdDebug(220) << name() << " icontext has changed, doUpdate=true" << endl; 00845 } 00846 else { 00847 //kdDebug(220) << name() << " icontext hasn't changed, doUpdate=false" << endl; 00848 } 00849 00850 if (!update) 00851 return; 00852 00853 if (doUpdate) 00854 doModeChange(); // tell buttons what happened 00855 00856 // ugly hack to force a QMainWindow::triggerLayout( true ) 00857 QMainWindow *mw = mainWindow(); 00858 if ( mw ) { 00859 mw->setUpdatesEnabled( false ); 00860 mw->setToolBarsMovable( !mw->toolBarsMovable() ); 00861 mw->setToolBarsMovable( !mw->toolBarsMovable() ); 00862 mw->setUpdatesEnabled( true ); 00863 } 00864 } 00865 00866 00867 KToolBar::IconText KToolBar::iconText() const 00868 { 00869 return d->m_iconText; 00870 } 00871 00872 00873 void KToolBar::setIconSize(int size) 00874 { 00875 setIconSize( size, true ); 00876 } 00877 00878 void KToolBar::setIconSize(int size, bool update) 00879 { 00880 bool doUpdate=false; 00881 00882 if ( size != d->m_iconSize ) { 00883 d->m_iconSize = size; 00884 doUpdate=true; 00885 } 00886 00887 if (!update) 00888 return; 00889 00890 if (doUpdate) 00891 doModeChange(); // tell buttons what happened 00892 00893 // ugly hack to force a QMainWindow::triggerLayout( true ) 00894 if ( mainWindow() ) { 00895 QMainWindow *mw = mainWindow(); 00896 mw->setUpdatesEnabled( false ); 00897 mw->setToolBarsMovable( !mw->toolBarsMovable() ); 00898 mw->setToolBarsMovable( !mw->toolBarsMovable() ); 00899 mw->setUpdatesEnabled( true ); 00900 } 00901 } 00902 00903 00904 int KToolBar::iconSize() const 00905 { 00906 if ( !d->m_iconSize ) // default value? 00907 return iconSizeDefault(); 00908 00909 return d->m_iconSize; 00910 } 00911 00912 int KToolBar::iconSizeDefault() const 00913 { 00914 if (!::qstrcmp(QObject::name(), "mainToolBar")) 00915 return KGlobal::iconLoader()->currentSize(KIcon::MainToolbar); 00916 00917 return KGlobal::iconLoader()->currentSize(KIcon::Toolbar); 00918 } 00919 00920 void KToolBar::setEnableContextMenu(bool enable ) 00921 { 00922 d->m_enableContext = enable; 00923 } 00924 00925 00926 bool KToolBar::contextMenuEnabled() const 00927 { 00928 return d->m_enableContext; 00929 } 00930 00931 00932 void KToolBar::setItemNoStyle(int id, bool no_style ) 00933 { 00934 KToolBarButton * button = getButton( id ); 00935 if (button) 00936 button->setNoStyle( no_style ); 00937 } 00938 00939 00940 void KToolBar::setFlat (bool flag) 00941 { 00942 if ( !mainWindow() ) 00943 return; 00944 if ( flag ) 00945 mainWindow()->moveDockWindow( this, DockMinimized ); 00946 else 00947 mainWindow()->moveDockWindow( this, DockTop ); 00948 // And remember to save the new look later 00949 KMainWindow *kmw = dynamic_cast<KMainWindow *>(mainWindow()); 00950 if ( kmw ) 00951 kmw->setSettingsDirty(); 00952 } 00953 00954 00955 int KToolBar::count() const 00956 { 00957 return id2widget.count(); 00958 } 00959 00960 00961 void KToolBar::saveState() 00962 { 00963 // first, try to save to the xml file 00964 if ( d->m_xmlguiClient && !d->m_xmlguiClient->xmlFile().isEmpty() ) { 00965 //kdDebug(220) << name() << " saveState: saving to " << d->m_xmlguiClient->xmlFile() << endl; 00966 QString barname(!::qstrcmp(name(), "unnamed") ? "mainToolBar" : name()); 00967 // try to find our toolbar 00968 d->modified = false; 00969 // go down one level to get to the right tags 00970 QDomElement current; 00971 for( QDomNode n = d->m_xmlguiClient->domDocument().documentElement().firstChild(); 00972 !n.isNull(); n = n.nextSibling()) { 00973 current = n.toElement(); 00974 00975 if ( current.tagName().lower() != "toolbar" ) 00976 continue; 00977 00978 QString curname(current.attribute( "name" )); 00979 00980 if ( curname == barname ) { 00981 saveState( current ); 00982 break; 00983 } 00984 } 00985 // if we didn't make changes, then just return 00986 if ( !d->modified ) 00987 return; 00988 00989 // now we load in the (non-merged) local file 00990 QString local_xml(KXMLGUIFactory::readConfigFile(d->m_xmlguiClient->xmlFile(), true, d->m_xmlguiClient->instance())); 00991 QDomDocument local; 00992 local.setContent(local_xml); 00993 00994 // make sure we don't append if this toolbar already exists locally 00995 bool just_append = true; 00996 00997 for( QDomNode n = local.documentElement().firstChild(); 00998 !n.isNull(); n = n.nextSibling()) { 00999 QDomElement elem = n.toElement(); 01000 01001 if ( elem.tagName().lower() != "toolbar" ) 01002 continue; 01003 01004 QString curname(elem.attribute( "name" )); 01005 01006 if ( curname == barname ) { 01007 just_append = false; 01008 local.documentElement().replaceChild( current, elem ); 01009 break; 01010 } 01011 } 01012 01013 if (just_append) 01014 local.documentElement().appendChild( current ); 01015 01016 KXMLGUIFactory::saveConfigFile(local, d->m_xmlguiClient->localXMLFile(), d->m_xmlguiClient->instance() ); 01017 01018 return; 01019 } 01020 01021 // if that didn't work, we save to the config file 01022 KConfig *config = KGlobal::config(); 01023 saveSettings(config, QString::null); 01024 config->sync(); 01025 } 01026 01027 QString KToolBar::settingsGroup() const 01028 { 01029 QString configGroup; 01030 if (!::qstrcmp(name(), "unnamed") || !::qstrcmp(name(), "mainToolBar")) 01031 configGroup = "Toolbar style"; 01032 else 01033 configGroup = QString(name()) + " Toolbar style"; 01034 if ( this->mainWindow() ) 01035 { 01036 configGroup.prepend(" "); 01037 configGroup.prepend( this->mainWindow()->name() ); 01038 } 01039 return configGroup; 01040 } 01041 01042 void KToolBar::saveSettings(KConfig *config, const QString &_configGroup) 01043 { 01044 QString configGroup = _configGroup; 01045 if (configGroup.isEmpty()) 01046 configGroup = settingsGroup(); 01047 //kdDebug(220) << name() << " saveSettings() group=" << _configGroup << " -> " << configGroup << endl; 01048 01049 QString position, icontext; 01050 int index; 01051 getAttributes( position, icontext, index ); 01052 01053 //kdDebug(220) << name() << " position=" << position << " index=" << index << " offset=" << offset() << " newLine=" << newLine() << endl; 01054 01055 KConfigGroupSaver saver(config, configGroup); 01056 01057 if(!config->hasDefault("Position") && position == d->PositionDefault ) 01058 config->revertToDefault("Position"); 01059 else 01060 config->writeEntry("Position", position); 01061 01062 //kdDebug(220) << name() << " icontext=" << icontext << " hasDefault:" << config->hasDefault( "IconText" ) << " d->IconTextDefault=" << d->IconTextDefault << endl; 01063 01064 if(d->m_honorStyle && icontext == d->IconTextDefault && !config->hasDefault("IconText") ) 01065 { 01066 //kdDebug(220) << name() << " reverting icontext to default" << endl; 01067 config->revertToDefault("IconText"); 01068 } 01069 else 01070 { 01071 //kdDebug(220) << name() << " writing icontext " << icontext << endl; 01072 config->writeEntry("IconText", icontext); 01073 } 01074 01075 if(!config->hasDefault("IconSize") && iconSize() == iconSizeDefault() ) 01076 config->revertToDefault("IconSize"); 01077 else 01078 config->writeEntry("IconSize", iconSize()); 01079 01080 if(!config->hasDefault("Hidden") && isHidden() == d->HiddenDefault ) 01081 config->revertToDefault("Hidden"); 01082 else 01083 config->writeEntry("Hidden", isHidden()); 01084 01085 // Note that index, unlike the other settings, depends on the other toolbars 01086 // So on the first run with a clean local config file, even the usual 01087 // hasDefault/==IndexDefault test would save the toolbar indexes 01088 // (IndexDefault was 0, whereas index is the real index in the GUI) 01089 // 01090 // Saving the whole set of indexes is necessary though. When moving only 01091 // one toolbar, if we only saved the changed indexes, the toolbars wouldn't 01092 // reappear at the same position the next time. 01093 // The whole set of indexes has to be saved. 01094 //kdDebug(220) << name() << " writing index " << index << endl; 01095 KMainWindow *kmw = dynamic_cast<KMainWindow *>(mainWindow()); 01096 // don't save if there's only one toolbar 01097 01098 // Don't use kmw->toolBarIterator() because you might 01099 // mess up someone else's iterator. Make the list on your own 01100 QPtrList<KToolBar> toolbarList; 01101 QPtrList<QToolBar> lst; 01102 for ( int i = (int)QMainWindow::DockUnmanaged; i <= (int)DockMinimized; ++i ) { 01103 lst = kmw->toolBars( (ToolBarDock)i ); 01104 for ( QToolBar *tb = lst.first(); tb; tb = lst.next() ) { 01105 if ( !tb->inherits( "KToolBar" ) ) 01106 continue; 01107 toolbarList.append( (KToolBar*)tb ); 01108 } 01109 } 01110 QPtrListIterator<KToolBar> toolbarIterator( toolbarList ); 01111 if ( !kmw || toolbarIterator.count() > 1 ) 01112 config->writeEntry("Index", index); 01113 else 01114 config->revertToDefault("Index"); 01115 01116 if(!config->hasDefault("Offset") && offset() == d->OffsetDefault ) 01117 config->revertToDefault("Offset"); 01118 else 01119 config->writeEntry("Offset", offset()); 01120 01121 if(!config->hasDefault("NewLine") && newLine() == d->NewLineDefault ) 01122 config->revertToDefault("NewLine"); 01123 else 01124 config->writeEntry("NewLine", newLine()); 01125 } 01126 01127 01128 void KToolBar::setXMLGUIClient( KXMLGUIClient *client ) 01129 { 01130 d->m_xmlguiClient = client; 01131 } 01132 01133 void KToolBar::setText( const QString & txt ) 01134 { 01135 setLabel( txt + " (" + kapp->caption() + ") " ); 01136 } 01137 01138 01139 QString KToolBar::text() const 01140 { 01141 return label(); 01142 } 01143 01144 01145 void KToolBar::doConnections( KToolBarButton *button ) 01146 { 01147 connect(button, SIGNAL(clicked(int)), this, SIGNAL( clicked( int ) ) ); 01148 connect(button, SIGNAL(doubleClicked(int)), this, SIGNAL( doubleClicked( int ) ) ); 01149 connect(button, SIGNAL(released(int)), this, SIGNAL( released( int ) ) ); 01150 connect(button, SIGNAL(pressed(int)), this, SIGNAL( pressed( int ) ) ); 01151 connect(button, SIGNAL(toggled(int)), this, SIGNAL( toggled( int ) ) ); 01152 connect(button, SIGNAL(highlighted(int, bool)), this, SIGNAL( highlighted( int, bool ) ) ); 01153 } 01154 01155 void KToolBar::mousePressEvent ( QMouseEvent *m ) 01156 { 01157 if ( !mainWindow() ) 01158 return; 01159 QMainWindow *mw = mainWindow(); 01160 if ( mw->toolBarsMovable() && d->m_enableContext ) { 01161 if ( m->button() == RightButton ) { 01162 QGuardedPtr<KToolBar> guard( this ); 01163 int i = contextMenu()->exec( m->globalPos(), 0 ); 01164 // "Configure Toolbars" recreates toolbars, so we might not exist anymore. 01165 if ( guard ) 01166 slotContextAboutToHide(); 01167 switch ( i ) { 01168 case -1: 01169 return; // popup canceled 01170 case CONTEXT_LEFT: 01171 mw->moveDockWindow( this, DockLeft ); 01172 break; 01173 case CONTEXT_RIGHT: 01174 mw->moveDockWindow( this, DockRight ); 01175 break; 01176 case CONTEXT_TOP: 01177 mw->moveDockWindow( this, DockTop ); 01178 break; 01179 case CONTEXT_BOTTOM: 01180 mw->moveDockWindow( this, DockBottom ); 01181 break; 01182 case CONTEXT_FLOAT: 01183 mw->moveDockWindow( this, DockTornOff ); 01184 break; 01185 case CONTEXT_FLAT: 01186 mw->moveDockWindow( this, DockMinimized ); 01187 break; 01188 case CONTEXT_ICONS: 01189 setIconText( IconOnly ); 01190 break; 01191 case CONTEXT_TEXTRIGHT: 01192 setIconText( IconTextRight ); 01193 break; 01194 case CONTEXT_TEXT: 01195 setIconText( TextOnly ); 01196 break; 01197 case CONTEXT_TEXTUNDER: 01198 setIconText( IconTextBottom ); 01199 break; 01200 default: 01201 if ( i >= CONTEXT_ICONSIZES ) 01202 setIconSize( i - CONTEXT_ICONSIZES ); 01203 else 01204 return; // assume this was an action handled elsewhere, no need for setSettingsDirty() 01205 } 01206 KMainWindow *kmw = dynamic_cast<KMainWindow *>(mw); 01207 if ( kmw ) 01208 kmw->setSettingsDirty(); 01209 } 01210 } 01211 } 01212 01213 void KToolBar::doModeChange() 01214 { 01215 for(QWidget *w=d->idleButtons.first(); w; w=d->idleButtons.next()) 01216 w->blockSignals(false); 01217 d->idleButtons.clear(); 01218 01219 emit modechange(); 01220 } 01221 01222 void KToolBar::rebuildLayout() 01223 { 01224 for(QWidget *w=d->idleButtons.first(); w; w=d->idleButtons.next()) 01225 w->blockSignals(false); 01226 d->idleButtons.clear(); 01227 01228 layoutTimer->stop(); 01229 QApplication::sendPostedEvents( this, QEvent::ChildInserted ); 01230 QBoxLayout *l = boxLayout(); 01231 01232 // clear the old layout 01233 QLayoutIterator it = l->iterator(); 01234 while ( it.current() ) 01235 it.deleteCurrent(); 01236 01237 for ( QWidget *w = widgets.first(); w; w = widgets.next() ) { 01238 if ( w == rightAligned ) 01239 continue; 01240 KToolBarSeparator *ktbs = dynamic_cast<KToolBarSeparator *>(w); 01241 if ( ktbs && !ktbs->showLine() ) { 01242 l->addSpacing( orientation() == Vertical ? w->sizeHint().height() : w->sizeHint().width() ); 01243 w->hide(); 01244 continue; 01245 } 01246 if ( dynamic_cast<QPopupMenu *>(w) ) // w is a QPopupMenu? 01247 continue; 01248 l->addWidget( w ); 01249 w->show(); 01250 if ((orientation() == Horizontal) && dynamic_cast<QLineEdit *>(w)) // w is QLineEdit ? 01251 l->addSpacing(2); // A little bit extra spacing behind it. 01252 } 01253 if ( rightAligned ) { 01254 l->addStretch(); 01255 l->addWidget( rightAligned ); 01256 rightAligned->show(); 01257 } 01258 01259 if ( fullSize() ) { 01260 if ( !rightAligned ) 01261 l->addStretch(); 01262 if ( stretchableWidget ) 01263 l->setStretchFactor( stretchableWidget, 10 ); 01264 } 01265 l->invalidate(); 01266 QApplication::postEvent( this, new QEvent( QEvent::LayoutHint ) ); 01267 } 01268 01269 void KToolBar::childEvent( QChildEvent *e ) 01270 { 01271 if ( e->child()->isWidgetType() ) { 01272 QWidget * w = dynamic_cast<QWidget *>(e->child()); 01273 if (!w || !(::qstrcmp( "qt_dockwidget_internal", w->name()))) 01274 { 01275 QToolBar::childEvent( e ); 01276 return; 01277 } 01278 if ( e->type() == QEvent::ChildInserted ) { 01279 if ( !dynamic_cast<QPopupMenu *>(w)) { // e->child() is not a QPopupMenu 01280 // prevent items that have been explicitly inserted by insert*() from 01281 // being inserted again 01282 if ( !widget2id.contains( w ) ) 01283 { 01284 int dummy = -1; 01285 insertWidgetInternal( w, dummy, -1 ); 01286 } 01287 } 01288 } else { 01289 removeWidgetInternal( w ); 01290 } 01291 if ( isVisibleTo( 0 ) ) 01292 { 01293 layoutTimer->start( 50, true ); 01294 QBoxLayout *l = boxLayout(); 01295 01296 // clear the old layout so that we don't get unnecassery layout 01297 // changes till we have rebuild the thing 01298 QLayoutIterator it = l->iterator(); 01299 while ( it.current() ) 01300 it.deleteCurrent(); 01301 } 01302 } 01303 QToolBar::childEvent( e ); 01304 } 01305 01306 void KToolBar::insertWidgetInternal( QWidget *w, int &index, int id ) 01307 { 01308 // we can't have it in widgets, or something is really wrong 01309 //widgets.removeRef( w ); 01310 01311 connect( w, SIGNAL( destroyed() ), 01312 this, SLOT( widgetDestroyed() ) ); 01313 if ( index == -1 || index > (int)widgets.count() ) { 01314 index = (int)widgets.count(); 01315 widgets.append( w ); 01316 } 01317 else 01318 widgets.insert( index, w ); 01319 if ( id == -1 ) 01320 id = id2widget.count(); 01321 id2widget.insert( id, w ); 01322 widget2id.insert( w, id ); 01323 } 01324 01325 void KToolBar::showEvent( QShowEvent *e ) 01326 { 01327 QToolBar::showEvent( e ); 01328 rebuildLayout(); 01329 } 01330 01331 void KToolBar::setStretchableWidget( QWidget *w ) 01332 { 01333 QToolBar::setStretchableWidget( w ); 01334 stretchableWidget = w; 01335 } 01336 01337 QSizePolicy KToolBar::sizePolicy() const 01338 { 01339 if ( orientation() == Horizontal ) 01340 return QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ); 01341 else 01342 return QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Expanding ); 01343 } 01344 01345 QSize KToolBar::sizeHint() const 01346 { 01347 QSize minSize(0,0); 01348 KToolBar *ncThis = const_cast<KToolBar *>(this); 01349 01350 ncThis->polish(); 01351 01352 int margin = static_cast<QWidget*>(ncThis)->layout()->margin() + frameWidth(); 01353 switch( barPos() ) 01354 { 01355 case KToolBar::Top: 01356 case KToolBar::Bottom: 01357 for ( QWidget *w = ncThis->widgets.first(); w; w = ncThis->widgets.next() ) 01358 { 01359 QSize sh = w->sizeHint(); 01360 if ( w->sizePolicy().horData() == QSizePolicy::Ignored ) 01361 sh.setWidth( 1 ); 01362 if ( w->sizePolicy().verData() == QSizePolicy::Ignored ) 01363 sh.setHeight( 1 ); 01364 sh = sh.boundedTo( w->maximumSize() ) 01365 .expandedTo( w->minimumSize() ).expandedTo( QSize(1, 1) ); 01366 01367 minSize = minSize.expandedTo(QSize(0, sh.height())); 01368 minSize += QSize(sh.width()+1, 0); 01369 if (dynamic_cast<QLineEdit *>(w)) // w is a QLineEdit ? 01370 minSize += QSize(2, 0); // A little bit extra spacing behind it. 01371 } 01372 01373 minSize += QSize(QApplication::style().pixelMetric( QStyle::PM_DockWindowHandleExtent ), 0); 01374 minSize += QSize(margin*2, margin*2); 01375 break; 01376 01377 case KToolBar::Left: 01378 case KToolBar::Right: 01379 for ( QWidget *w = ncThis->widgets.first(); w; w = ncThis->widgets.next() ) 01380 { 01381 QSize sh = w->sizeHint(); 01382 if ( w->sizePolicy().horData() == QSizePolicy::Ignored ) 01383 sh.setWidth( 1 ); 01384 if ( w->sizePolicy().verData() == QSizePolicy::Ignored ) 01385 sh.setHeight( 1 ); 01386 sh = sh.boundedTo( w->maximumSize() ) 01387 .expandedTo( w->minimumSize() ).expandedTo( QSize(1, 1) ); 01388 01389 minSize = minSize.expandedTo(QSize(sh.width(), 0)); 01390 minSize += QSize(0, sh.height()+1); 01391 } 01392 minSize += QSize(0, QApplication::style().pixelMetric( QStyle::PM_DockWindowHandleExtent )); 01393 minSize += QSize(margin*2, margin*2); 01394 break; 01395 01396 default: 01397 minSize = QToolBar::sizeHint(); 01398 break; 01399 } 01400 return minSize; 01401 } 01402 01403 QSize KToolBar::minimumSize() const 01404 { 01405 return minimumSizeHint(); 01406 } 01407 01408 QSize KToolBar::minimumSizeHint() const 01409 { 01410 return sizeHint(); 01411 } 01412 01413 bool KToolBar::highlight() const 01414 { 01415 return d->m_highlight; 01416 } 01417 01418 void KToolBar::hide() 01419 { 01420 QToolBar::hide(); 01421 } 01422 01423 void KToolBar::show() 01424 { 01425 QToolBar::show(); 01426 } 01427 01428 void KToolBar::resizeEvent( QResizeEvent *e ) 01429 { 01430 bool b = isUpdatesEnabled(); 01431 setUpdatesEnabled( false ); 01432 QToolBar::resizeEvent( e ); 01433 if (b) 01434 { 01435 if (layoutTimer->isActive()) 01436 { 01437 // Wait with repainting till layout is complete. 01438 d->repaintTimer.start( 100, true ); 01439 } 01440 else 01441 { 01442 // Repaint now 01443 slotRepaint(); 01444 } 01445 } 01446 } 01447 01448 void KToolBar::slotIconChanged(int group) 01449 { 01450 if ((group != KIcon::Toolbar) && (group != KIcon::MainToolbar)) 01451 return; 01452 if ((group == KIcon::MainToolbar) != !::qstrcmp(name(), "mainToolBar")) 01453 return; 01454 01455 doModeChange(); 01456 01457 if (isVisible()) 01458 updateGeometry(); 01459 } 01460 01461 void KToolBar::slotReadConfig() 01462 { 01463 //kdDebug(220) << name() << " slotReadConfig" << endl; 01464 // Read appearance settings (hmm, we used to do both here, 01465 // but a well behaved application will call applyMainWindowSettings 01466 // anyway, right ?) 01467 applyAppearanceSettings(KGlobal::config(), QString::null ); 01468 } 01469 01470 void KToolBar::slotAppearanceChanged() 01471 { 01472 // Read appearance settings from global file. 01473 applyAppearanceSettings(KGlobal::config(), QString::null, true /* lose local settings */ ); 01474 01475 // And remember to save the new look later 01476 KMainWindow *kmw = dynamic_cast<KMainWindow *>(mainWindow()); 01477 if ( kmw ) 01478 kmw->setSettingsDirty(); 01479 } 01480 01481 //static 01482 bool KToolBar::highlightSetting() 01483 { 01484 QString grpToolbar(QString::fromLatin1("Toolbar style")); 01485 KConfigGroupSaver saver(KGlobal::config(), grpToolbar); 01486 return KGlobal::config()->readBoolEntry(QString::fromLatin1("Highlighting"),true); 01487 } 01488 01489 //static 01490 bool KToolBar::transparentSetting() 01491 { 01492 QString grpToolbar(QString::fromLatin1("Toolbar style")); 01493 KConfigGroupSaver saver(KGlobal::config(), grpToolbar); 01494 return KGlobal::config()->readBoolEntry(QString::fromLatin1("TransparentMoving"),true); 01495 } 01496 01497 //static 01498 KToolBar::IconText KToolBar::iconTextSetting() 01499 { 01500 QString grpToolbar(QString::fromLatin1("Toolbar style")); 01501 KConfigGroupSaver saver(KGlobal::config(), grpToolbar); 01502 QString icontext = KGlobal::config()->readEntry(QString::fromLatin1("IconText"),QString::fromLatin1("IconOnly")); 01503 if ( icontext == "IconTextRight" ) 01504 return IconTextRight; 01505 else if ( icontext == "IconTextBottom" ) 01506 return IconTextBottom; 01507 else if ( icontext == "TextOnly" ) 01508 return TextOnly; 01509 else 01510 return IconOnly; 01511 } 01512 01513 void KToolBar::applyAppearanceSettings(KConfig *config, const QString &_configGroup, bool forceGlobal) 01514 { 01515 QString configGroup = _configGroup.isEmpty() ? settingsGroup() : _configGroup; 01516 //kdDebug(220) << name() << " applyAppearanceSettings: configGroup=" << configGroup << " forceGlobal=" << forceGlobal << endl; 01517 01518 // If we have application-specific settings in the XML file, 01519 // and nothing in the application's config file, then 01520 // we don't apply the global defaults, the XML ones are preferred 01521 // (see applySettings for a full explanation) 01522 // This is the reason for the xmlgui tests below. 01523 bool xmlgui = d->m_xmlguiClient && !d->m_xmlguiClient->xmlFile().isEmpty(); 01524 01525 KConfig *gconfig = KGlobal::config(); 01526 01527 static const QString &attrIconText = KGlobal::staticQString("IconText"); 01528 static const QString &attrHighlight = KGlobal::staticQString("Highlighting"); 01529 static const QString &attrTrans = KGlobal::staticQString("TransparentMoving"); 01530 static const QString &attrIconSize = KGlobal::staticQString("IconSize"); 01531 01532 // we actually do this in two steps. 01533 // First, we read in the global styles [Toolbar style] (from the KControl module). 01534 // Then, if the toolbar is NOT 'mainToolBar', we will also try to read in [barname Toolbar style] 01535 bool highlight; 01536 int transparent; 01537 bool applyIconText = !xmlgui; // if xmlgui is used, global defaults won't apply 01538 bool applyIconSize = !xmlgui; 01539 01540 int iconSize = d->IconSizeDefault; 01541 QString iconText = d->IconTextDefault; 01542 01543 // this is the first iteration 01544 QString grpToolbar(QString::fromLatin1("Toolbar style")); 01545 { // start block for KConfigGroupSaver 01546 KConfigGroupSaver saver(gconfig, grpToolbar); 01547 01548 // first, get the generic settings 01549 highlight = gconfig->readBoolEntry(attrHighlight, true); 01550 transparent = gconfig->readBoolEntry(attrTrans, true); 01551 01552 // we read in the IconText property *only* if we intend on actually 01553 // honoring it 01554 if (d->m_honorStyle) 01555 d->IconTextDefault = gconfig->readEntry(attrIconText, d->IconTextDefault); 01556 else 01557 d->IconTextDefault = "IconOnly"; 01558 01559 // Use the default icon size for toolbar icons. 01560 d->IconSizeDefault = gconfig->readNumEntry(attrIconSize, d->IconSizeDefault); 01561 01562 iconSize = d->IconSizeDefault; 01563 iconText = d->IconTextDefault; 01564 01565 if ( !forceGlobal && config->hasGroup(configGroup) ) 01566 { 01567 config->setGroup(configGroup); 01568 01569 // first, get the generic settings 01570 highlight = config->readBoolEntry(attrHighlight, highlight); 01571 transparent = config->readBoolEntry(attrTrans, transparent); 01572 01573 // read in the IconText property 01574 if ( config->hasKey( attrIconText ) ) { 01575 iconText = config->readEntry(attrIconText); 01576 applyIconText = true; 01577 //kdDebug(220) << name() << " read icontext=" << d->IconTextDefault << ", that will be the default" << endl; 01578 } 01579 01580 // now get the size 01581 if ( config->hasKey( attrIconSize ) ) { 01582 iconSize = config->readNumEntry(attrIconSize); 01583 applyIconSize = true; 01584 } 01585 } 01586 01587 // revert back to the old group 01588 } // end block for KConfigGroupSaver 01589 01590 bool doUpdate = false; 01591 01592 IconText icon_text; 01593 if ( iconText == "IconTextRight" ) 01594 icon_text = IconTextRight; 01595 else if ( iconText == "IconTextBottom" ) 01596 icon_text = IconTextBottom; 01597 else if ( iconText == "TextOnly" ) 01598 icon_text = TextOnly; 01599 else 01600 icon_text = IconOnly; 01601 01602 // check if the icon/text has changed 01603 if (icon_text != d->m_iconText && applyIconText) { 01604 //kdDebug(220) << name() << " applyAppearanceSettings setIconText " << icon_text << endl; 01605 setIconText(icon_text, false); 01606 doUpdate = true; 01607 } 01608 01609 // ...and check if the icon size has changed 01610 if (iconSize != d->m_iconSize && applyIconSize) { 01611 setIconSize(iconSize, false); 01612 doUpdate = true; 01613 } 01614 01615 QMainWindow *mw = mainWindow(); 01616 01617 // ...and if we should highlight 01618 if ( highlight != d->m_highlight ) { 01619 d->m_highlight = highlight; 01620 doUpdate = true; 01621 } 01622 01623 // ...and if we should move transparently 01624 if ( mw && transparent != (!mw->opaqueMoving()) ) { 01625 mw->setOpaqueMoving( !transparent ); 01626 } 01627 01628 if (doUpdate) 01629 doModeChange(); // tell buttons what happened 01630 01631 if (isVisible ()) 01632 updateGeometry(); 01633 } 01634 01635 void KToolBar::applySettings(KConfig *config, const QString &_configGroup) 01636 { 01637 return applySettings(config,_configGroup,false); 01638 } 01639 01640 void KToolBar::applySettings(KConfig *config, const QString &_configGroup, bool force) 01641 { 01642 //kdDebug(220) << name() << " applySettings group=" << _configGroup << endl; 01643 01644 QString configGroup = _configGroup.isEmpty() ? settingsGroup() : _configGroup; 01645 01646 /* 01647 Let's explain this a bit more in details. 01648 The order in which we apply settings is : 01649 Global config / <appnamerc> user settings if no XMLGUI is used 01650 Global config / App-XML attributes / <appnamerc> user settings if XMLGUI is used 01651 01652 So in the first case, we simply read everything from KConfig as below, 01653 but in the second case we don't do anything here if there is no app-specific config, 01654 and the XMLGUI-related code (loadState()) uses the static methods of this class 01655 to get the global defaults. 01656 01657 Global config doesn't include position (index, offset, newline and hidden/shown). 01658 */ 01659 01660 // First the appearance stuff - the one which has a global config 01661 applyAppearanceSettings( config, configGroup ); 01662 01663 // ...and now the position stuff 01664 if ( config->hasGroup(configGroup) || force ) 01665 { 01666 KConfigGroupSaver cgs(config, configGroup); 01667 01668 static const QString &attrPosition = KGlobal::staticQString("Position"); 01669 static const QString &attrIndex = KGlobal::staticQString("Index"); 01670 static const QString &attrOffset = KGlobal::staticQString("Offset"); 01671 static const QString &attrNewLine = KGlobal::staticQString("NewLine"); 01672 static const QString &attrHidden = KGlobal::staticQString("Hidden"); 01673 01674 QString position = config->readEntry(attrPosition, d->PositionDefault); 01675 int index = config->readNumEntry(attrIndex, -1); 01676 int offset = config->readNumEntry(attrOffset, d->OffsetDefault); 01677 bool newLine = config->readBoolEntry(attrNewLine, d->NewLineDefault); 01678 bool hidden = config->readBoolEntry(attrHidden, d->HiddenDefault); 01679 01680 Dock pos(DockTop); 01681 if ( position == "Top" ) 01682 pos = DockTop; 01683 else if ( position == "Bottom" ) 01684 pos = DockBottom; 01685 else if ( position == "Left" ) 01686 pos = DockLeft; 01687 else if ( position == "Right" ) 01688 pos = DockRight; 01689 else if ( position == "Floating" ) 01690 pos = DockTornOff; 01691 else if ( position == "Flat" ) 01692 pos = DockMinimized; 01693 01694 //kdDebug(220) << name() << " applySettings hidden=" << hidden << endl; 01695 if (hidden) 01696 hide(); 01697 else 01698 show(); 01699 01700 if ( mainWindow() ) 01701 { 01702 //kdDebug(220) << name() << " applySettings updating ToolbarInfo" << endl; 01703 d->toolBarInfo = KToolBarPrivate::ToolBarInfo( pos, index, newLine, offset ); 01704 positionYourself( true ); 01705 } 01706 if (isVisible ()) 01707 updateGeometry(); 01708 } 01709 } 01710 01711 bool KToolBar::event( QEvent *e ) 01712 { 01713 if ( (e->type() == QEvent::LayoutHint) && isUpdatesEnabled() ) 01714 d->repaintTimer.start( 100, true ); 01715 01716 if (e->type() == QEvent::ChildInserted ) 01717 { 01718 // Bypass QToolBar::event, 01719 // it will show() the inserted child and we don't want to 01720 // do that until we have rebuilt the layout. 01721 childEvent((QChildEvent *)e); 01722 return true; 01723 } 01724 01725 return QToolBar::event( e ); 01726 } 01727 01728 void KToolBar::slotRepaint() 01729 { 01730 setUpdatesEnabled( false ); 01731 // Send a resizeEvent to update the "toolbar extension arrow" 01732 // (The button you get when your toolbar-items don't fit in 01733 // the available space) 01734 QResizeEvent ev(size(), size()); 01735 resizeEvent(&ev); 01736 QApplication::sendPostedEvents( this, QEvent::LayoutHint ); 01737 setUpdatesEnabled( true ); 01738 repaint( true ); 01739 } 01740 01741 void KToolBar::toolBarPosChanged( QToolBar *tb ) 01742 { 01743 if ( tb != this ) 01744 return; 01745 if ( d->oldPos == DockMinimized ) 01746 rebuildLayout(); 01747 d->oldPos = (QMainWindow::ToolBarDock)barPos(); 01748 KMainWindow *kmw = dynamic_cast<KMainWindow *>(mainWindow()); 01749 if ( kmw ) 01750 kmw->setSettingsDirty(); 01751 } 01752 01753 static KToolBar::Dock stringToDock( const QString& attrPosition ) 01754 { 01755 KToolBar::Dock dock = KToolBar::DockTop; 01756 if ( !attrPosition.isEmpty() ) { 01757 if ( attrPosition == "top" ) 01758 dock = KToolBar::DockTop; 01759 else if ( attrPosition == "left" ) 01760 dock = KToolBar::DockLeft; 01761 else if ( attrPosition == "right" ) 01762 dock = KToolBar::DockRight; 01763 else if ( attrPosition == "bottom" ) 01764 dock = KToolBar::DockBottom; 01765 else if ( attrPosition == "floating" ) 01766 dock = KToolBar::DockTornOff; 01767 else if ( attrPosition == "flat" ) 01768 dock = KToolBar::DockMinimized; 01769 } 01770 return dock; 01771 } 01772 01773 01774 void KToolBar::loadState( const QDomElement &element ) 01775 { 01776 QMainWindow *mw = mainWindow(); 01777 01778 if ( !mw ) 01779 return; 01780 01781 { 01782 QCString text = element.namedItem( "text" ).toElement().text().utf8(); 01783 if ( text.isEmpty() ) 01784 text = element.namedItem( "Text" ).toElement().text().utf8(); 01785 if ( !text.isEmpty() ) 01786 setText( i18n( text ) ); 01787 } 01788 01789 { 01790 QCString attrFullWidth = element.attribute( "fullWidth" ).lower().latin1(); 01791 if ( !attrFullWidth.isEmpty() ) 01792 setFullSize( attrFullWidth == "true" ); 01793 } 01794 01795 /* 01796 This method is called in order to load toolbar settings from XML. 01797 However this can be used in two rather different cases: 01798 - for the initial loading of the app's XML. In that case the settings 01799 are only the defaults, the user's KConfig settings will override them 01800 (KDE4 TODO: how about saving those user settings into the local XML file instead? 01801 Then this whole thing would be simpler, no KConfig settings to apply afterwards. 01802 OTOH we'd have to migrate those settings when the .rc version increases, 01803 like we do for shortcuts) 01804 01805 - for later re-loading when switching between parts in KXMLGUIFactory. 01806 In that case the XML contains the final settings, not the defaults. 01807 We do need the defaults, and the toolbar might have been completely 01808 deleted and recreated meanwhile. So we store the app-default settings 01809 into the XML. 01810 */ 01811 bool loadingAppDefaults = true; 01812 if ( element.hasAttribute( "offsetDefault" ) ) 01813 { 01814 // this isn't the first time, so the defaults have been saved into the (in-memory) XML 01815 loadingAppDefaults = false; 01816 d->OffsetDefault = element.attribute( "offsetDefault" ).toInt(); 01817 d->NewLineDefault = element.attribute( "newlineDefault" ) == "true"; 01818 d->HiddenDefault = element.attribute( "hiddenDefault" ) == "true"; 01819 d->IconSizeDefault = element.attribute( "iconSizeDefault" ).toInt(); 01820 d->PositionDefault = element.attribute( "positionDefault" ); 01821 d->IconTextDefault = element.attribute( "iconTextDefault" ); 01822 } 01823 //kdDebug(220) << name() << " loadState loadingAppDefaults=" << loadingAppDefaults << endl; 01824 01825 Dock dock = stringToDock( element.attribute( "position" ).lower() ); 01826 01827 { 01828 QCString attrIconText = element.attribute( "iconText" ).lower().latin1(); 01829 if ( !attrIconText.isEmpty() ) { 01830 //kdDebug(220) << name() << " loadState attrIconText=" << attrIconText << endl; 01831 if ( attrIconText == "icontextright" ) 01832 setIconText( KToolBar::IconTextRight ); 01833 else if ( attrIconText == "textonly" ) 01834 setIconText( KToolBar::TextOnly ); 01835 else if ( attrIconText == "icontextbottom" ) 01836 setIconText( KToolBar::IconTextBottom ); 01837 else if ( attrIconText == "icononly" ) 01838 setIconText( KToolBar::IconOnly ); 01839 } else 01840 { 01841 //kdDebug(220) << name() << " loadState no iconText attribute in XML, using iconTextSetting=" << iconTextSetting() << endl; 01842 // Use global setting 01843 if (d->m_honorStyle) 01844 setIconText( iconTextSetting() ); 01845 else 01846 setIconText( d->IconTextDefault ); 01847 } 01848 } 01849 01850 QString attrIconSize = element.attribute( "iconSize" ).lower(); 01851 int iconSize = d->IconSizeDefault; 01852 if ( !attrIconSize.isEmpty() ) 01853 iconSize = attrIconSize.toInt(); 01854 setIconSize( iconSize ); 01855 01856 int index = -1; // append by default. This is very important, otherwise 01857 // with all 0 indexes, we keep reversing the toolbars. 01858 { 01859 QString attrIndex = element.attribute( "index" ).lower(); 01860 if ( !attrIndex.isEmpty() ) 01861 index = attrIndex.toInt(); 01862 } 01863 01864 int offset = d->OffsetDefault; 01865 bool newLine = d->NewLineDefault; 01866 bool hidden = d->HiddenDefault; 01867 01868 { 01869 QString attrOffset = element.attribute( "offset" ); 01870 if ( !attrOffset.isEmpty() ) 01871 offset = attrOffset.toInt(); 01872 } 01873 01874 { 01875 QString attrNewLine = element.attribute( "newline" ).lower(); 01876 if ( !attrNewLine.isEmpty() ) 01877 newLine = attrNewLine == "true"; 01878 } 01879 01880 { 01881 QString attrHidden = element.attribute( "hidden" ).lower(); 01882 if ( !attrHidden.isEmpty() ) { 01883 hidden = attrHidden == "true"; 01884 } 01885 } 01886 01887 d->toolBarInfo = KToolBarPrivate::ToolBarInfo( dock, index, newLine, offset ); 01888 mw->addDockWindow( this, dock, newLine ); 01889 mw->moveDockWindow( this, dock, newLine, index, offset ); 01890 01891 // Apply the highlight button setting 01892 d->m_highlight = highlightSetting(); 01893 01894 if ( hidden ) 01895 hide(); 01896 else 01897 show(); 01898 01899 if ( loadingAppDefaults ) 01900 { 01901 getAttributes( d->PositionDefault, d->IconTextDefault, index ); 01902 //kdDebug(220) << name() << " loadState IconTextDefault=" << d->IconTextDefault << endl; 01903 d->OffsetDefault = offset; 01904 d->NewLineDefault = newLine; 01905 d->HiddenDefault = hidden; 01906 d->IconSizeDefault = iconSize; 01907 } 01908 //kdDebug(220) << name() << " loadState hidden=" << hidden << endl; 01909 01910 // Apply transparent-toolbar-moving setting (ok, this is global to the mainwindow, 01911 // but we do it only if there are toolbars...) 01912 // KDE4: move to KMainWindow 01913 if ( transparentSetting() != !mw->opaqueMoving() ) 01914 mw->setOpaqueMoving( !transparentSetting() ); 01915 } 01916 01917 int KToolBar::dockWindowIndex() 01918 { 01919 int index = 0; 01920 Q_ASSERT( mainWindow() ); 01921 if ( mainWindow() ) { 01922 QMainWindow::ToolBarDock dock; 01923 bool newLine; 01924 int offset; 01925 mainWindow()->getLocation( this, dock, index, newLine, offset ); 01926 } 01927 return index; 01928 } 01929 01930 void KToolBar::getAttributes( QString &position, QString &icontext, int &index ) 01931 { 01932 // get all of the stuff to save 01933 switch ( barPos() ) { 01934 case KToolBar::Flat: 01935 position = "Flat"; 01936 break; 01937 case KToolBar::Bottom: 01938 position = "Bottom"; 01939 break; 01940 case KToolBar::Left: 01941 position = "Left"; 01942 break; 01943 case KToolBar::Right: 01944 position = "Right"; 01945 break; 01946 case KToolBar::Floating: 01947 position = "Floating"; 01948 break; 01949 case KToolBar::Top: 01950 default: 01951 position = "Top"; 01952 break; 01953 } 01954 01955 index = dockWindowIndex(); 01956 01957 switch (d->m_iconText) { 01958 case KToolBar::IconTextRight: 01959 icontext = "IconTextRight"; 01960 break; 01961 case KToolBar::IconTextBottom: 01962 icontext = "IconTextBottom"; 01963 break; 01964 case KToolBar::TextOnly: 01965 icontext = "TextOnly"; 01966 break; 01967 case KToolBar::IconOnly: 01968 default: 01969 icontext = "IconOnly"; 01970 break; 01971 } 01972 //kdDebug(220) << name() << " getAttributes: icontext=" << icontext << endl; 01973 } 01974 01975 void KToolBar::saveState( QDomElement ¤t ) 01976 { 01977 Q_ASSERT( !current.isNull() ); 01978 QString position, icontext; 01979 int index = -1; 01980 getAttributes( position, icontext, index ); 01981 01982 current.setAttribute( "noMerge", "1" ); 01983 current.setAttribute( "position", position ); 01984 current.setAttribute( "iconText", icontext ); 01985 current.setAttribute( "index", index ); 01986 current.setAttribute( "offset", offset() ); 01987 current.setAttribute( "newline", newLine() ); 01988 if ( isHidden() ) 01989 current.setAttribute( "hidden", "true" ); 01990 d->modified = true; 01991 01992 // TODO if this method is used by more than KXMLGUIBuilder, e.g. to save XML settings to *disk*, 01993 // then the stuff below shouldn't always be done. 01994 current.setAttribute( "offsetDefault", d->OffsetDefault ); 01995 current.setAttribute( "newlineDefault", d->NewLineDefault ); 01996 current.setAttribute( "hiddenDefault", d->HiddenDefault ? "true" : "false" ); 01997 current.setAttribute( "iconSizeDefault", d->IconSizeDefault ); 01998 current.setAttribute( "positionDefault", d->PositionDefault ); 01999 current.setAttribute( "iconTextDefault", d->IconTextDefault ); 02000 02001 //kdDebug(220) << name() << " saveState: saving index=" << index << " iconText=" << icontext << " hidden=" << isHidden() << endl; 02002 } 02003 02004 // Called by KMainWindow::finalizeGUI 02005 void KToolBar::positionYourself( bool force ) 02006 { 02007 if (force) 02008 d->positioned = false; 02009 02010 if ( d->positioned || !mainWindow() ) 02011 { 02012 //kdDebug(220) << name() << " positionYourself d->positioned=true ALREADY DONE" << endl; 02013 return; 02014 } 02015 // we can't test for ForceHide after moveDockWindow because QDockArea 02016 // does a reparent() with showIt == true 02017 bool hidden = isHidden(); 02018 //kdDebug(220) << name() << " positionYourself dock=" << d->toolBarInfo.dock << " newLine=" << d->toolBarInfo.newline << " index=" << d->toolBarInfo.index << " offset=" << d->toolBarInfo.offset << endl; 02019 mainWindow()->moveDockWindow( this, d->toolBarInfo.dock, 02020 d->toolBarInfo.newline, 02021 d->toolBarInfo.index, 02022 d->toolBarInfo.offset ); 02023 02024 //kdDebug(220) << name() << " positionYourself dockWindowIndex=" << dockWindowIndex() << endl; 02025 if ( hidden ) 02026 hide(); 02027 else 02028 show(); 02029 // This method can only have an effect once - unless force is set 02030 d->positioned = true; 02031 } 02032 02033 KPopupMenu *KToolBar::contextMenu() 02034 { 02035 if ( context ) 02036 return context; 02037 // Construct our context popup menu. Name it qt_dockwidget_internal so it 02038 // won't be deleted by QToolBar::clear(). 02039 context = new KPopupMenu( this, "qt_dockwidget_internal" ); 02040 context->insertTitle(i18n("Toolbar Menu")); 02041 02042 KPopupMenu *orient = new KPopupMenu( context, "orient" ); 02043 orient->insertItem( i18n("toolbar position string","Top"), CONTEXT_TOP ); 02044 orient->insertItem( i18n("toolbar position string","Left"), CONTEXT_LEFT ); 02045 orient->insertItem( i18n("toolbar position string","Right"), CONTEXT_RIGHT ); 02046 orient->insertItem( i18n("toolbar position string","Bottom"), CONTEXT_BOTTOM ); 02047 orient->insertSeparator(-1); 02048 orient->insertItem( i18n("toolbar position string","Floating"), CONTEXT_FLOAT ); 02049 orient->insertItem( i18n("min toolbar", "Flat"), CONTEXT_FLAT ); 02050 02051 KPopupMenu *mode = new KPopupMenu( context, "mode" ); 02052 mode->insertItem( i18n("Icons Only"), CONTEXT_ICONS ); 02053 mode->insertItem( i18n("Text Only"), CONTEXT_TEXT ); 02054 mode->insertItem( i18n("Text Alongside Icons"), CONTEXT_TEXTRIGHT ); 02055 mode->insertItem( i18n("Text Under Icons"), CONTEXT_TEXTUNDER ); 02056 02057 KPopupMenu *size = new KPopupMenu( context, "size" ); 02058 size->insertItem( i18n("Default"), CONTEXT_ICONSIZES ); 02059 // Query the current theme for available sizes 02060 KIconTheme *theme = KGlobal::instance()->iconLoader()->theme(); 02061 QValueList<int> avSizes; 02062 if (theme) 02063 { 02064 if (!::qstrcmp(QObject::name(), "mainToolBar")) 02065 avSizes = theme->querySizes( KIcon::MainToolbar); 02066 else 02067 avSizes = theme->querySizes( KIcon::Toolbar); 02068 } 02069 02070 d->iconSizes = avSizes; 02071 qHeapSort(avSizes); 02072 02073 QValueList<int>::Iterator it; 02074 if (avSizes.count() < 10) { 02075 // Fixed or threshold type icons 02076 QValueList<int>::Iterator end(avSizes.end()); 02077 for (it=avSizes.begin(); it!=end; ++it) { 02078 QString text; 02079 if ( *it < 19 ) 02080 text = i18n("Small (%1x%2)").arg(*it).arg(*it); 02081 else if (*it < 25) 02082 text = i18n("Medium (%1x%2)").arg(*it).arg(*it); 02083 else if (*it < 35) 02084 text = i18n("Large (%1x%2)").arg(*it).arg(*it); 02085 else 02086 text = i18n("Huge (%1x%2)").arg(*it).arg(*it); 02087 //we use the size as an id, with an offset 02088 size->insertItem( text, CONTEXT_ICONSIZES + *it ); 02089 } 02090 } 02091 else { 02092 // Scalable icons. 02093 const int progression[] = {16, 22, 32, 48, 64, 96, 128, 192, 256}; 02094 02095 it = avSizes.begin(); 02096 for (uint i = 0; i < 9; i++) { 02097 while (it++ != avSizes.end()) { 02098 if (*it >= progression[i]) { 02099 QString text; 02100 if ( *it < 19 ) 02101 text = i18n("Small (%1x%2)").arg(*it).arg(*it); 02102 else if (*it < 25) 02103 text = i18n("Medium (%1x%2)").arg(*it).arg(*it); 02104 else if (*it < 35) 02105 text = i18n("Large (%1x%2)").arg(*it).arg(*it); 02106 else 02107 text = i18n("Huge (%1x%2)").arg(*it).arg(*it); 02108 //we use the size as an id, with an offset 02109 size->insertItem( text, CONTEXT_ICONSIZES + *it ); 02110 break; 02111 } 02112 } 02113 } 02114 } 02115 02116 context->insertItem( i18n("Orientation"), orient ); 02117 orient->setItemChecked(CONTEXT_TOP, true); 02118 context->insertItem( i18n("Text Position"), mode ); 02119 context->setItemChecked(CONTEXT_ICONS, true); 02120 context->insertItem( i18n("Icon Size"), size ); 02121 02122 connect( context, SIGNAL( aboutToShow() ), this, SLOT( slotContextAboutToShow() ) ); 02123 // Unplugging a submenu from abouttohide leads to the popupmenu floating around 02124 // So better simply call that code from after exec() returns (DF) 02125 //connect( context, SIGNAL( aboutToHide() ), this, SLOT( slotContextAboutToHide() ) ); 02126 return context; 02127 } 02128 02129 void KToolBar::slotContextAboutToShow() 02130 { 02131 // The idea here is to reuse the "static" part of the menu to save time. 02132 // But the "Toolbars" action is dynamic (can be a single action or a submenu) 02133 // and ToolBarHandler::setupActions() deletes it, so better not keep it around. 02134 // So we currently plug/unplug the last two actions of the menu. 02135 // Another way would be to keep around the actions and plug them all into a (new each time) popupmenu. 02136 KMainWindow *kmw = dynamic_cast<KMainWindow *>(mainWindow()); 02137 if ( kmw ) { 02138 kmw->setupToolbarMenuActions(); 02139 // Only allow hiding a toolbar if the action is also plugged somewhere else (e.g. menubar) 02140 KAction *tbAction = kmw->toolBarMenuAction(); 02141 if ( tbAction && tbAction->containerCount() > 0 ) 02142 tbAction->plug(context); 02143 } 02144 02145 // try to find "configure toolbars" action 02146 KAction *configureAction = 0; 02147 const char* actionName = KStdAction::name(KStdAction::ConfigureToolbars); 02148 if ( d->m_xmlguiClient ) 02149 configureAction = d->m_xmlguiClient->actionCollection()->action(actionName); 02150 if ( !configureAction && kmw ) 02151 configureAction = kmw->actionCollection()->action(actionName); 02152 if ( configureAction ) 02153 configureAction->plug(context); 02154 KEditToolbar::setDefaultToolbar(QObject::name()); 02155 02156 for(int i = CONTEXT_ICONS; i <= CONTEXT_TEXTUNDER; ++i) 02157 context->setItemChecked(i, false); 02158 02159 switch( d->m_iconText ) 02160 { 02161 case IconOnly: 02162 default: 02163 context->setItemChecked(CONTEXT_ICONS, true); 02164 break; 02165 case IconTextRight: 02166 context->setItemChecked(CONTEXT_TEXTRIGHT, true); 02167 break; 02168 case TextOnly: 02169 context->setItemChecked(CONTEXT_TEXT, true); 02170 break; 02171 case IconTextBottom: 02172 context->setItemChecked(CONTEXT_TEXTUNDER, true); 02173 break; 02174 } 02175 02176 QValueList<int>::ConstIterator iIt = d->iconSizes.begin(); 02177 QValueList<int>::ConstIterator iEnd = d->iconSizes.end(); 02178 for (; iIt != iEnd; ++iIt ) 02179 context->setItemChecked( CONTEXT_ICONSIZES + *iIt, false ); 02180 02181 context->setItemChecked( CONTEXT_ICONSIZES, false ); 02182 02183 context->setItemChecked( CONTEXT_ICONSIZES + d->m_iconSize, true ); 02184 02185 for ( int i = CONTEXT_TOP; i <= CONTEXT_FLAT; ++i ) 02186 context->setItemChecked( i, false ); 02187 02188 switch ( barPos() ) 02189 { 02190 case KToolBar::Flat: 02191 context->setItemChecked( CONTEXT_FLAT, true ); 02192 break; 02193 case KToolBar::Bottom: 02194 context->setItemChecked( CONTEXT_BOTTOM, true ); 02195 break; 02196 case KToolBar::Left: 02197 context->setItemChecked( CONTEXT_LEFT, true ); 02198 break; 02199 case KToolBar::Right: 02200 context->setItemChecked( CONTEXT_RIGHT, true ); 02201 break; 02202 case KToolBar::Floating: 02203 context->setItemChecked( CONTEXT_FLOAT, true ); 02204 break; 02205 case KToolBar::Top: 02206 context->setItemChecked( CONTEXT_TOP, true ); 02207 break; 02208 default: break; 02209 } 02210 } 02211 02212 void KToolBar::slotContextAboutToHide() 02213 { 02214 // We have to unplug whatever slotContextAboutToShow plugged into the menu. 02215 // Unplug the toolbar menu action 02216 KMainWindow *kmw = dynamic_cast<KMainWindow *>(mainWindow()); 02217 if ( kmw && kmw->toolBarMenuAction() ) 02218 if ( kmw->toolBarMenuAction()->containerCount() > 1 ) 02219 kmw->toolBarMenuAction()->unplug(context); 02220 02221 // Unplug the configure toolbars action too, since it's afterwards anyway 02222 KAction *configureAction = 0; 02223 const char* actionName = KStdAction::name(KStdAction::ConfigureToolbars); 02224 if ( d->m_xmlguiClient ) 02225 configureAction = d->m_xmlguiClient->actionCollection()->action(actionName); 02226 if ( !configureAction && kmw ) 02227 configureAction = kmw->actionCollection()->action(actionName); 02228 if ( configureAction ) 02229 configureAction->unplug(context); 02230 02231 QPtrListIterator<QWidget> it( widgets ); 02232 QWidget *wdg; 02233 while ( ( wdg = it.current() ) != 0 ) { 02234 if ( wdg->inherits( "QToolButton" ) ) 02235 static_cast<QToolButton*>( wdg )->setDown( false ); 02236 ++it; 02237 } 02238 } 02239 02240 void KToolBar::widgetDestroyed() 02241 { 02242 removeWidgetInternal( (QWidget*)sender() ); 02243 } 02244 02245 void KToolBar::removeWidgetInternal( QWidget * w ) 02246 { 02247 widgets.removeRef( w ); 02248 QMap< QWidget*, int >::Iterator it = widget2id.find( w ); 02249 if ( it == widget2id.end() ) 02250 return; 02251 id2widget.remove( *it ); 02252 widget2id.remove( it ); 02253 } 02254 02255 void KToolBar::virtual_hook( int, void* ) 02256 { /*BASE::virtual_hook( id, data );*/ } 02257 02258 #include "ktoolbar.moc" 02259