• Skip to content
  • Skip to link menu
KDE 4.7 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDEUI

ktoolbar.cpp
Go to the documentation of this file.
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     (C) 2005-2006 Hamish Rodda (rodda@kde.org)
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Library General Public
00014     License version 2 as published by the Free Software Foundation.
00015 
00016     This library is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019     Library General Public License for more details.
00020 
00021     You should have received a copy of the GNU Library General Public License
00022     along with this library; see the file COPYING.LIB.  If not, write to
00023     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00024     Boston, MA 02110-1301, USA.
00025 */
00026 
00027 #include "ktoolbar.h"
00028 
00029 #include <config.h>
00030 
00031 #include <QtCore/QPointer>
00032 #include <QtGui/QDesktopWidget>
00033 #include <QtGui/QFrame>
00034 #include <QtGui/QLayout>
00035 #include <QtGui/QMouseEvent>
00036 #include <QtGui/QToolButton>
00037 #include <QtXml/QDomElement>
00038 
00039 #include <kaction.h>
00040 #include <kactioncollection.h>
00041 #include <kapplication.h>
00042 #include <kauthorized.h>
00043 #include <kconfig.h>
00044 #include <kdebug.h>
00045 #include <kedittoolbar.h>
00046 #include <kglobalsettings.h>
00047 #include <kguiitem.h>
00048 #include <kicon.h>
00049 #include <kiconloader.h>
00050 #include <klocale.h>
00051 #include <kxmlguiwindow.h>
00052 #include <kmenu.h>
00053 #include <kstandardaction.h>
00054 #include <ktoggleaction.h>
00055 #include <kxmlguifactory.h>
00056 
00057 #include <kconfiggroup.h>
00058 
00059 /*
00060  Toolbar settings (e.g. icon size or toolButtonStyle)
00061  =====================================================
00062 
00063  We have the following stack of settings (in order of priority) :
00064    - user-specified settings (loaded/saved in KConfig)
00065    - developer-specified settings in the XMLGUI file (if using xmlgui) (cannot change at runtime)
00066    - KDE-global default (user-configurable; can change at runtime)
00067  and when switching between kparts, they are saved as xml in memory,
00068  which, in the unlikely case of no-kmainwindow-autosaving, could be
00069  different from the user-specified settings saved in KConfig and would have
00070  priority over it.
00071 
00072  So, in summary, without XML:
00073    Global config / User settings (loaded/saved in kconfig)
00074  and with XML:
00075    Global config / App-XML attributes / User settings (loaded/saved in kconfig)
00076 
00077  And all those settings (except the KDE-global defaults) have to be stored in memory
00078  since we cannot retrieve them at random points in time, not knowing the xml document
00079  nor config file that holds these settings. Hence the iconSizeSettings and toolButtonStyleSettings arrays.
00080 
00081  For instance, if you change the KDE-global default, whether this makes a change
00082  on a given toolbar depends on whether there are settings at Level_AppXML or Level_UserSettings.
00083  Only if there are no settings at those levels, should the change of KDEDefault make a difference.
00084 */
00085 enum SettingLevel { Level_KDEDefault, Level_AppXML, Level_UserSettings,
00086                     NSettingLevels };
00087 enum { Unset = -1 };
00088 
00089 class KToolBar::Private
00090 {
00091   public:
00092     Private(KToolBar *qq)
00093       : q(qq),
00094         isMainToolBar(false),
00095 #ifndef KDE_NO_DEPRECATED
00096         enableContext(true),
00097 #endif
00098         unlockedMovable(true),
00099         xmlguiClient(0),
00100         contextOrient(0),
00101         contextMode(0),
00102         contextSize(0),
00103         contextButtonTitle(0),
00104         contextShowText(0),
00105         contextButtonAction(0),
00106         contextTop(0),
00107         contextLeft(0),
00108         contextRight(0),
00109         contextBottom(0),
00110         contextIcons(0),
00111         contextTextRight(0),
00112         contextText(0),
00113         contextTextUnder(0),
00114         contextLockAction(0),
00115         dropIndicatorAction(0),
00116         context(0),
00117         dragAction(0)
00118     {
00119     }
00120 
00121     void slotAppearanceChanged();
00122     void slotContextAboutToShow();
00123     void slotContextAboutToHide();
00124     void slotContextLeft();
00125     void slotContextRight();
00126     void slotContextShowText();
00127     void slotContextTop();
00128     void slotContextBottom();
00129     void slotContextIcons();
00130     void slotContextText();
00131     void slotContextTextRight();
00132     void slotContextTextUnder();
00133     void slotContextIconSize();
00134     void slotLockToolBars(bool lock);
00135 
00136     void init(bool readConfig = true, bool isMainToolBar = false);
00137     QString getPositionAsString() const;
00138     KMenu *contextMenu(const QPoint &globalPos);
00139     void setLocked(bool locked);
00140     void adjustSeparatorVisibility();
00141     void loadKDESettings();
00142     void applyCurrentSettings();
00143 
00144     static Qt::ToolButtonStyle toolButtonStyleFromString(const QString& style);
00145     static QString toolButtonStyleToString(Qt::ToolButtonStyle);
00146     static Qt::ToolBarArea positionFromString(const QString& position);
00147 
00148     KToolBar *q;
00149     bool isMainToolBar : 1;
00150 #ifndef KDE_NO_DEPRECATED
00151     bool enableContext : 1;
00152 #endif
00153     bool unlockedMovable : 1;
00154     static bool s_editable;
00155     static bool s_locked;
00156 
00157     KXMLGUIClient *xmlguiClient;
00158 
00159     QMenu* contextOrient;
00160     QMenu* contextMode;
00161     QMenu* contextSize;
00162 
00163     QAction* contextButtonTitle;
00164     QAction* contextShowText;
00165     QAction* contextButtonAction;
00166     QAction* contextTop;
00167     QAction* contextLeft;
00168     QAction* contextRight;
00169     QAction* contextBottom;
00170     QAction* contextIcons;
00171     QAction* contextTextRight;
00172     QAction* contextText;
00173     QAction* contextTextUnder;
00174     KToggleAction* contextLockAction;
00175     QMap<QAction*,int> contextIconSizes;
00176 
00177     class IntSetting
00178     {
00179     public:
00180         IntSetting() {
00181             for (int level = 0; level < NSettingLevels; ++level) {
00182                 values[level] = Unset;
00183             }
00184         }
00185         int currentValue() const {
00186             int val = Unset;
00187             for (int level = 0; level < NSettingLevels; ++level) {
00188                 if (values[level] != Unset)
00189                     val = values[level];
00190             }
00191             return val;
00192         }
00193         // Default value as far as the user is concerned is kde-global + app-xml.
00194         // If currentValue()==defaultValue() then nothing to write into kconfig.
00195         int defaultValue() const {
00196             int val = Unset;
00197             for (int level = 0; level < Level_UserSettings; ++level) {
00198                 if (values[level] != Unset)
00199                     val = values[level];
00200             }
00201             return val;
00202         }
00203         QString toString() const {
00204             QString str;
00205             for (int level = 0; level < NSettingLevels; ++level) {
00206                 str += QString::number(values[level]) + ' ';
00207             }
00208             return str;
00209         }
00210         int& operator[](int index) { return values[index]; }
00211     private:
00212         int values[NSettingLevels];
00213     };
00214     IntSetting iconSizeSettings;
00215     IntSetting toolButtonStyleSettings; // either Qt::ToolButtonStyle or -1, hence "int".
00216 
00217     QList<QAction*> actionsBeingDragged;
00218     QAction* dropIndicatorAction;
00219 
00220     KMenu* context;
00221     KAction* dragAction;
00222     QPoint dragStartPosition;
00223 };
00224 
00225 bool KToolBar::Private::s_editable = false;
00226 bool KToolBar::Private::s_locked = true;
00227 
00228 void KToolBar::Private::init(bool readConfig, bool _isMainToolBar)
00229 {
00230   isMainToolBar = _isMainToolBar;
00231   loadKDESettings();
00232 
00233   // also read in our configurable settings (for non-xmlgui toolbars)
00234   // KDE5: we can probably remove this, if people save settings then they load them too, e.g. using KMainWindow's autosave.
00235   if (readConfig) {
00236       KConfigGroup cg(KGlobal::config(), QString());
00237       q->applySettings(cg);
00238   }
00239 
00240   if (q->mainWindow()) {
00241     // Get notified when settings change
00242     connect(q, SIGNAL(allowedAreasChanged(Qt::ToolBarAreas)),
00243              q->mainWindow(), SLOT(setSettingsDirty()));
00244     connect(q, SIGNAL(iconSizeChanged(const QSize&)),
00245              q->mainWindow(), SLOT(setSettingsDirty()));
00246     connect(q, SIGNAL(toolButtonStyleChanged(Qt::ToolButtonStyle)),
00247              q->mainWindow(), SLOT(setSettingsDirty()));
00248     connect(q, SIGNAL(movableChanged(bool)),
00249              q->mainWindow(), SLOT(setSettingsDirty()));
00250     connect(q, SIGNAL(orientationChanged(Qt::Orientation)),
00251              q->mainWindow(), SLOT(setSettingsDirty()));
00252   }
00253 
00254   if (!KAuthorized::authorize("movable_toolbars"))
00255     q->setMovable(false);
00256   else
00257     q->setMovable(!KToolBar::toolBarsLocked());
00258 
00259   connect(q, SIGNAL(movableChanged(bool)),
00260            q, SLOT(slotMovableChanged(bool)));
00261 
00262   q->setAcceptDrops(true);
00263 
00264   connect(KGlobalSettings::self(), SIGNAL(toolbarAppearanceChanged(int)),
00265           q, SLOT(slotAppearanceChanged()));
00266   connect(KIconLoader::global(), SIGNAL(iconLoaderSettingsChanged()),
00267           q, SLOT(slotAppearanceChanged()));
00268 }
00269 
00270 QString KToolBar::Private::getPositionAsString() const
00271 {
00272   // get all of the stuff to save
00273   switch (q->mainWindow()->toolBarArea(const_cast<KToolBar*>(q))) {
00274     case Qt::BottomToolBarArea:
00275       return "Bottom";
00276     case Qt::LeftToolBarArea:
00277       return "Left";
00278     case Qt::RightToolBarArea:
00279       return "Right";
00280     case Qt::TopToolBarArea:
00281     default:
00282       return "Top";
00283   }
00284 }
00285 
00286 KMenu *KToolBar::Private::contextMenu(const QPoint &globalPos)
00287 {
00288   if (!context) {
00289     context = new KMenu(q);
00290 
00291     contextButtonTitle = context->addTitle(i18nc("@title:menu", "Show Text"));
00292     contextShowText = context->addAction(QString(), q, SLOT(slotContextShowText()));
00293 
00294     context->addTitle(i18nc("@title:menu", "Toolbar Settings"));
00295 
00296     contextOrient = new KMenu(i18n("Orientation"), context);
00297 
00298     contextTop = contextOrient->addAction(i18nc("toolbar position string", "Top"), q, SLOT(slotContextTop()));
00299     contextTop->setChecked(true);
00300     contextLeft = contextOrient->addAction(i18nc("toolbar position string", "Left"), q, SLOT(slotContextLeft()));
00301     contextRight = contextOrient->addAction(i18nc("toolbar position string", "Right"), q, SLOT(slotContextRight()));
00302     contextBottom = contextOrient->addAction(i18nc("toolbar position string", "Bottom"), q, SLOT(slotContextBottom()));
00303 
00304     QActionGroup* positionGroup = new QActionGroup(contextOrient);
00305     foreach (QAction* action, contextOrient->actions()) {
00306       action->setActionGroup(positionGroup);
00307       action->setCheckable(true);
00308     }
00309 
00310     contextMode = new KMenu(i18n("Text Position"), context);
00311 
00312     contextIcons = contextMode->addAction(i18n("Icons Only"), q, SLOT(slotContextIcons()));
00313     contextText = contextMode->addAction(i18n("Text Only"), q, SLOT(slotContextText()));
00314     contextTextRight = contextMode->addAction(i18n("Text Alongside Icons"), q, SLOT(slotContextTextRight()));
00315     contextTextUnder = contextMode->addAction(i18n("Text Under Icons"), q, SLOT(slotContextTextUnder()));
00316 
00317     QActionGroup* textGroup = new QActionGroup(contextMode);
00318     foreach (QAction* action, contextMode->actions()) {
00319       action->setActionGroup(textGroup);
00320       action->setCheckable(true);
00321     }
00322 
00323     contextSize = new KMenu(i18n("Icon Size"), context);
00324 
00325     contextIconSizes.insert(contextSize->addAction(i18nc("@item:inmenu Icon size", "Default"), q, SLOT(slotContextIconSize())),
00326                             iconSizeSettings.defaultValue());
00327 
00328     // Query the current theme for available sizes
00329     KIconTheme *theme = KIconLoader::global()->theme();
00330     QList<int> avSizes;
00331     if (theme) {
00332         avSizes = theme->querySizes(isMainToolBar ? KIconLoader::MainToolbar : KIconLoader::Toolbar);
00333     }
00334 
00335     qSort(avSizes);
00336 
00337     if (avSizes.count() < 10) {
00338       // Fixed or threshold type icons
00339       foreach (int it, avSizes) {
00340         QString text;
00341         if (it < 19)
00342           text = i18n("Small (%1x%2)", it, it);
00343         else if (it < 25)
00344           text = i18n("Medium (%1x%2)", it, it);
00345         else if (it < 35)
00346           text = i18n("Large (%1x%2)", it, it);
00347         else
00348           text = i18n("Huge (%1x%2)", it, it);
00349 
00350         // save the size in the contextIconSizes map
00351         contextIconSizes.insert(contextSize->addAction(text, q, SLOT(slotContextIconSize())), it);
00352       }
00353     } else {
00354       // Scalable icons.
00355       const int progression[] = { 16, 22, 32, 48, 64, 96, 128, 192, 256 };
00356 
00357       for (uint i = 0; i < 9; i++) {
00358         foreach (int it, avSizes) {
00359           if (it >= progression[ i ]) {
00360             QString text;
00361             if (it < 19)
00362               text = i18n("Small (%1x%2)", it, it);
00363             else if (it < 25)
00364               text = i18n("Medium (%1x%2)", it, it);
00365             else if (it < 35)
00366               text = i18n("Large (%1x%2)", it, it);
00367             else
00368               text = i18n("Huge (%1x%2)", it, it);
00369 
00370             // save the size in the contextIconSizes map
00371             contextIconSizes.insert(contextSize->addAction(text, q, SLOT(slotContextIconSize())), it);
00372             break;
00373           }
00374         }
00375       }
00376     }
00377 
00378     QActionGroup* sizeGroup = new QActionGroup(contextSize);
00379     foreach (QAction* action, contextSize->actions()) {
00380       action->setActionGroup(sizeGroup);
00381       action->setCheckable(true);
00382     }
00383 
00384     if (!q->toolBarsLocked() && !q->isMovable())
00385       unlockedMovable = false;
00386 
00387     delete contextLockAction;
00388     contextLockAction = new KToggleAction(KIcon("system-lock-screen"), i18n("Lock Toolbar Positions"), q);
00389     contextLockAction->setChecked(q->toolBarsLocked());
00390     connect(contextLockAction, SIGNAL(toggled(bool)), q, SLOT(slotLockToolBars(bool)));
00391 
00392     // Now add the actions to the menu
00393     context->addMenu(contextMode);
00394     context->addMenu(contextSize);
00395     context->addMenu(contextOrient);
00396     context->addSeparator();
00397 
00398     connect(context, SIGNAL(aboutToShow()), q, SLOT(slotContextAboutToShow()));
00399   }
00400 
00401   contextButtonAction = q->actionAt(q->mapFromGlobal(globalPos));
00402   if (contextButtonAction) {
00403       contextShowText->setText(contextButtonAction->text());
00404       contextShowText->setIcon(contextButtonAction->icon());
00405       contextShowText->setCheckable(true);
00406   }
00407 
00408   contextOrient->menuAction()->setVisible(!q->toolBarsLocked());
00409   // Unplugging a submenu from abouttohide leads to the popupmenu floating around
00410   // So better simply call that code from after exec() returns (DF)
00411   //connect(context, SIGNAL(aboutToHide()), this, SLOT(slotContextAboutToHide()));
00412 
00413   return context;
00414 }
00415 
00416 void KToolBar::Private::setLocked(bool locked)
00417 {
00418   if (unlockedMovable)
00419     q->setMovable(!locked);
00420 }
00421 
00422 void KToolBar::Private::adjustSeparatorVisibility()
00423 {
00424   bool visibleNonSeparator = false;
00425   int separatorToShow = -1;
00426 
00427   for (int index = 0; index < q->actions().count(); ++index) {
00428     QAction* action = q->actions()[ index ];
00429     if (action->isSeparator()) {
00430       if (visibleNonSeparator) {
00431         separatorToShow = index;
00432         visibleNonSeparator = false;
00433       } else {
00434         action->setVisible(false);
00435       }
00436     } else if (!visibleNonSeparator) {
00437       if (action->isVisible()) {
00438         visibleNonSeparator = true;
00439         if (separatorToShow != -1) {
00440           q->actions()[ separatorToShow ]->setVisible(true);
00441           separatorToShow = -1;
00442         }
00443       }
00444     }
00445   }
00446 
00447   if (separatorToShow != -1)
00448     q->actions()[ separatorToShow ]->setVisible(false);
00449 }
00450 
00451 Qt::ToolButtonStyle KToolBar::Private::toolButtonStyleFromString(const QString & _style)
00452 {
00453   QString style = _style.toLower();
00454   if (style == "textbesideicon" || style == "icontextright")
00455     return Qt::ToolButtonTextBesideIcon;
00456   else if (style == "textundericon" || style == "icontextbottom")
00457     return Qt::ToolButtonTextUnderIcon;
00458   else if (style == "textonly")
00459     return Qt::ToolButtonTextOnly;
00460   else
00461     return Qt::ToolButtonIconOnly;
00462 }
00463 
00464 QString KToolBar::Private::toolButtonStyleToString(Qt::ToolButtonStyle style)
00465 {
00466   switch(style)
00467   {
00468     case Qt::ToolButtonIconOnly:
00469     default:
00470       return "IconOnly";
00471     case Qt::ToolButtonTextBesideIcon:
00472       return "TextBesideIcon";
00473     case Qt::ToolButtonTextOnly:
00474       return "TextOnly";
00475     case Qt::ToolButtonTextUnderIcon:
00476       return "TextUnderIcon";
00477   }
00478 }
00479 
00480 Qt::ToolBarArea KToolBar::Private::positionFromString(const QString& position)
00481 {
00482     Qt::ToolBarArea newposition = Qt::TopToolBarArea;
00483     if (position == QLatin1String("left")) {
00484         newposition = Qt::LeftToolBarArea;
00485     } else if (position == QLatin1String("bottom")) {
00486         newposition = Qt::BottomToolBarArea;
00487     } else if (position == QLatin1String("right")) {
00488         newposition = Qt::RightToolBarArea;
00489     }
00490     return newposition;
00491 }
00492 
00493 // Global setting was changed
00494 void KToolBar::Private::slotAppearanceChanged()
00495 {
00496     loadKDESettings();
00497     applyCurrentSettings();
00498 }
00499 
00500 void KToolBar::Private::loadKDESettings()
00501 {
00502     iconSizeSettings[Level_KDEDefault] = q->iconSizeDefault();
00503 
00504     if (isMainToolBar) {
00505         toolButtonStyleSettings[Level_KDEDefault] = q->toolButtonStyleSetting();
00506     } else {
00507         const QString fallBack = toolButtonStyleToString(Qt::ToolButtonTextBesideIcon);
00523         KConfigGroup group(KGlobal::config(), "Toolbar style");
00524         const QString value = group.readEntry("ToolButtonStyleOtherToolbars", fallBack);
00525         toolButtonStyleSettings[Level_KDEDefault] = KToolBar::Private::toolButtonStyleFromString(value);
00526     }
00527 }
00528 
00529 // Call this after changing something in d->iconSizeSettings or d->toolButtonStyleSettings
00530 void KToolBar::Private::applyCurrentSettings()
00531 {
00532     //kDebug() << q->objectName() << "iconSizeSettings:" << iconSizeSettings.toString() << "->" << iconSizeSettings.currentValue();
00533     const int currentIconSize = iconSizeSettings.currentValue();
00534     q->setIconSize(QSize(currentIconSize, currentIconSize));
00535     //kDebug() << q->objectName() << "toolButtonStyleSettings:" << toolButtonStyleSettings.toString() << "->" << toolButtonStyleSettings.currentValue();
00536     q->setToolButtonStyle(static_cast<Qt::ToolButtonStyle>(toolButtonStyleSettings.currentValue()));
00537 
00538     // And remember to save the new look later
00539     KMainWindow *kmw = q->mainWindow();
00540     if (kmw)
00541         kmw->setSettingsDirty();
00542 }
00543 
00544 void KToolBar::Private::slotContextAboutToShow()
00545 {
00554   KXmlGuiWindow *kmw = qobject_cast<KXmlGuiWindow *>(q->mainWindow());
00555 
00556   // try to find "configure toolbars" action
00557   QAction *configureAction = 0;
00558   const char* actionName = KStandardAction::name(KStandardAction::ConfigureToolbars);
00559   if (xmlguiClient) {
00560     configureAction = xmlguiClient->actionCollection()->action(actionName);
00561   }
00562 
00563   if (!configureAction && kmw) {
00564     configureAction = kmw->actionCollection()->action(actionName);
00565   }
00566 
00567   if (configureAction) {
00568     context->addAction(configureAction);
00569   }
00570 
00571   context->addAction(contextLockAction);
00572 
00573   if (kmw) {
00574     kmw->setupToolbarMenuActions();
00575     // Only allow hiding a toolbar if the action is also plugged somewhere else (e.g. menubar)
00576     QAction *tbAction = kmw->toolBarMenuAction();
00577     if (!q->toolBarsLocked() && tbAction && tbAction->associatedWidgets().count() > 0)
00578       context->addAction(tbAction);
00579   }
00580 
00581   KEditToolBar::setGlobalDefaultToolBar(q->QObject::objectName().toLatin1().constData());
00582 
00583   // Check the actions that should be checked
00584   switch (q->toolButtonStyle()) {
00585     case Qt::ToolButtonIconOnly:
00586     default:
00587       contextIcons->setChecked(true);
00588       break;
00589     case Qt::ToolButtonTextBesideIcon:
00590       contextTextRight->setChecked(true);
00591       break;
00592     case Qt::ToolButtonTextOnly:
00593       contextText->setChecked(true);
00594       break;
00595     case Qt::ToolButtonTextUnderIcon:
00596       contextTextUnder->setChecked(true);
00597       break;
00598   }
00599 
00600   QMapIterator< QAction*, int > it = contextIconSizes;
00601   while (it.hasNext()) {
00602     it.next();
00603     if (it.value() == q->iconSize().width()) {
00604       it.key()->setChecked(true);
00605       break;
00606     }
00607   }
00608 
00609   switch (q->mainWindow()->toolBarArea(q)) {
00610     case Qt::BottomToolBarArea:
00611       contextBottom->setChecked(true);
00612       break;
00613     case Qt::LeftToolBarArea:
00614       contextLeft->setChecked(true);
00615       break;
00616     case Qt::RightToolBarArea:
00617       contextRight->setChecked(true);
00618       break;
00619     default:
00620     case Qt::TopToolBarArea:
00621       contextTop->setChecked(true);
00622       break;
00623   }
00624 
00625   const bool showButtonSettings = contextButtonAction
00626                                   && !contextShowText->text().isEmpty()
00627                                   && contextTextRight->isChecked();
00628   contextButtonTitle->setVisible(showButtonSettings);
00629   contextShowText->setVisible(showButtonSettings);
00630   if (showButtonSettings) {
00631     contextShowText->setChecked(contextButtonAction->priority() >= QAction::NormalPriority);
00632   }
00633 }
00634 
00635 void KToolBar::Private::slotContextAboutToHide()
00636 {
00637   // We have to unplug whatever slotContextAboutToShow plugged into the menu.
00638   // Unplug the toolbar menu action
00639   KXmlGuiWindow *kmw = qobject_cast<KXmlGuiWindow *>(q->mainWindow());
00640   if (kmw && kmw->toolBarMenuAction()) {
00641     if (kmw->toolBarMenuAction()->associatedWidgets().count() > 1) {
00642       context->removeAction(kmw->toolBarMenuAction());
00643     }
00644   }
00645 
00646   // Unplug the configure toolbars action too, since it's afterwards anyway
00647   QAction *configureAction = 0;
00648   const char* actionName = KStandardAction::name(KStandardAction::ConfigureToolbars);
00649   if (xmlguiClient) {
00650     configureAction = xmlguiClient->actionCollection()->action(actionName);
00651   }
00652 
00653   if (!configureAction && kmw) {
00654     configureAction = kmw->actionCollection()->action(actionName);
00655   }
00656 
00657   if (configureAction) {
00658     context->removeAction(configureAction);
00659   }
00660 
00661   context->removeAction(contextLockAction);
00662 }
00663 
00664 void KToolBar::Private::slotContextLeft()
00665 {
00666   q->mainWindow()->addToolBar(Qt::LeftToolBarArea, q);
00667 }
00668 
00669 void KToolBar::Private::slotContextRight()
00670 {
00671   q->mainWindow()->addToolBar(Qt::RightToolBarArea, q);
00672 }
00673 
00674 void KToolBar::Private::slotContextShowText()
00675 {
00676     Q_ASSERT(contextButtonAction);
00677     const QAction::Priority priority = contextShowText->isChecked()
00678                                        ? QAction::NormalPriority : QAction::LowPriority;
00679     contextButtonAction->setPriority(priority);
00680 
00681     // Save the priority state of the action
00682     const KComponentData& componentData = KGlobal::mainComponent();
00683     const QString componentName = componentData.componentName() + "ui.rc";
00684     const QString configFile = KXMLGUIFactory::readConfigFile(componentName, componentData);
00685 
00686     QDomDocument document;
00687     document.setContent(configFile);
00688     QDomElement elem = KXMLGUIFactory::actionPropertiesElement(document);
00689     QDomElement actionElem = KXMLGUIFactory::findActionByName(elem, contextButtonAction->objectName(), true);
00690     actionElem.setAttribute("priority", priority);
00691     KXMLGUIFactory::saveConfigFile(document, componentName, componentData);
00692 }
00693 
00694 void KToolBar::Private::slotContextTop()
00695 {
00696   q->mainWindow()->addToolBar(Qt::TopToolBarArea, q);
00697 }
00698 
00699 void KToolBar::Private::slotContextBottom()
00700 {
00701   q->mainWindow()->addToolBar(Qt::BottomToolBarArea, q);
00702 }
00703 
00704 void KToolBar::Private::slotContextIcons()
00705 {
00706     q->setToolButtonStyle(Qt::ToolButtonIconOnly);
00707     toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
00708 }
00709 
00710 void KToolBar::Private::slotContextText()
00711 {
00712     q->setToolButtonStyle(Qt::ToolButtonTextOnly);
00713     toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
00714 }
00715 
00716 void KToolBar::Private::slotContextTextUnder()
00717 {
00718     q->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
00719     toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
00720 }
00721 
00722 void KToolBar::Private::slotContextTextRight()
00723 {
00724     q->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
00725     toolButtonStyleSettings[Level_UserSettings] = q->toolButtonStyle();
00726 }
00727 
00728 void KToolBar::Private::slotContextIconSize()
00729 {
00730     QAction* action = qobject_cast<QAction*>(q->sender());
00731     if (action && contextIconSizes.contains(action)) {
00732         const int iconSize = contextIconSizes.value(action);
00733         q->setIconDimensions(iconSize);
00734     }
00735 }
00736 
00737 void KToolBar::Private::slotLockToolBars(bool lock)
00738 {
00739   q->setToolBarsLocked(lock);
00740 }
00741 
00742 
00743 
00744 KToolBar::KToolBar(QWidget *parent, bool isMainToolBar, bool readConfig)
00745   : QToolBar(parent),
00746     d(new Private(this))
00747 {
00748   d->init(readConfig, isMainToolBar);
00749 
00750   // KToolBar is auto-added to the top area of the main window if parent is a QMainWindow
00751   if (QMainWindow* mw = qobject_cast<QMainWindow*>(parent))
00752     mw->addToolBar(this);
00753 }
00754 
00755 KToolBar::KToolBar(const QString& objectName, QWidget *parent, bool readConfig)
00756   : QToolBar(parent),
00757     d(new Private(this))
00758 {
00759     setObjectName(objectName);
00760     // mainToolBar -> isMainToolBar = true  -> buttonStyle is configurable
00761     // others      -> isMainToolBar = false -> ### hardcoded default for buttonStyle !!! should be configurable? -> hidden key added
00762     d->init(readConfig, objectName == "mainToolBar");
00763 
00764     // KToolBar is auto-added to the top area of the main window if parent is a QMainWindow
00765     if (QMainWindow* mw = qobject_cast<QMainWindow*>(parent))
00766         mw->addToolBar(this);
00767 }
00768 
00769 KToolBar::KToolBar(const QString& objectName, QMainWindow* parent, Qt::ToolBarArea area,
00770                     bool newLine, bool isMainToolBar, bool readConfig)
00771   : QToolBar(parent),
00772     d(new Private(this))
00773 {
00774   setObjectName(objectName);
00775   d->init(readConfig, isMainToolBar);
00776 
00777   if (newLine)
00778     mainWindow()->addToolBarBreak(area);
00779 
00780   mainWindow()->addToolBar(area, this);
00781 
00782   if (newLine)
00783     mainWindow()->addToolBarBreak(area);
00784 }
00785 
00786 KToolBar::~KToolBar()
00787 {
00788   delete d->contextLockAction;
00789   delete d;
00790 }
00791 
00792 #ifndef KDE_NO_DEPRECATED
00793 void KToolBar::setContextMenuEnabled(bool enable)
00794 {
00795   d->enableContext = enable;
00796 }
00797 #endif
00798 
00799 #ifndef KDE_NO_DEPRECATED
00800 bool KToolBar::contextMenuEnabled() const
00801 {
00802   return d->enableContext;
00803 }
00804 #endif
00805 
00806 void KToolBar::saveSettings(KConfigGroup &cg)
00807 {
00808     Q_ASSERT(!cg.name().isEmpty());
00809 
00810     cg.deleteEntry("Hidden"); // remove old key to avoid bugs from the compat code in applySettings. KDE5: remove.
00811 
00812     const int currentIconSize = iconSize().width();
00813     //kDebug() << objectName() << currentIconSize << d->iconSizeSettings.toString() << "defaultValue=" << d->iconSizeSettings.defaultValue();
00814     if (!cg.hasDefault("IconSize") && currentIconSize == d->iconSizeSettings.defaultValue()) {
00815         cg.revertToDefault("IconSize");
00816         d->iconSizeSettings[Level_UserSettings] = Unset;
00817     } else {
00818         cg.writeEntry("IconSize", currentIconSize);
00819         d->iconSizeSettings[Level_UserSettings] = currentIconSize;
00820     }
00821 
00822     const Qt::ToolButtonStyle currentToolButtonStyle = toolButtonStyle();
00823     if (!cg.hasDefault("ToolButtonStyle") && currentToolButtonStyle == d->toolButtonStyleSettings.defaultValue()) {
00824         cg.revertToDefault("ToolButtonStyle");
00825         d->toolButtonStyleSettings[Level_UserSettings] = Unset;
00826     } else {
00827         cg.writeEntry("ToolButtonStyle", d->toolButtonStyleToString(currentToolButtonStyle));
00828         d->toolButtonStyleSettings[Level_UserSettings] = currentToolButtonStyle;
00829     }
00830 }
00831 
00832 void KToolBar::setXMLGUIClient(KXMLGUIClient *client)
00833 {
00834     d->xmlguiClient = client;
00835 }
00836 
00837 void KToolBar::contextMenuEvent(QContextMenuEvent* event)
00838 {
00839 #ifndef KDE_NO_DEPRECATED
00840     if (mainWindow() && d->enableContext) {
00841         QPointer<KToolBar> guard(this);
00842         const QPoint globalPos = event->globalPos();
00843         d->contextMenu(globalPos)->exec(globalPos);
00844 
00845         // "Configure Toolbars" recreates toolbars, so we might not exist anymore.
00846         if (guard) {
00847             d->slotContextAboutToHide();
00848         }
00849         return;
00850     }
00851 #endif
00852 
00853     QToolBar::contextMenuEvent(event);
00854 }
00855 
00856 Qt::ToolButtonStyle KToolBar::toolButtonStyleSetting()
00857 {
00858     KConfigGroup group(KGlobal::config(), "Toolbar style");
00859     const QString fallback = Private::toolButtonStyleToString(Qt::ToolButtonTextBesideIcon);
00860     return KToolBar::Private::toolButtonStyleFromString(group.readEntry("ToolButtonStyle", fallback));
00861 }
00862 
00863 void KToolBar::loadState(const QDomElement &element)
00864 {
00865     QMainWindow *mw = mainWindow();
00866     if (!mw)
00867         return;
00868 
00869     {
00870         QDomNode textNode = element.namedItem("text");
00871         QByteArray text;
00872         QByteArray context;
00873         if (textNode.isElement())
00874         {
00875             QDomElement textElement = textNode.toElement();
00876             text = textElement.text().toUtf8();
00877             context = textElement.attribute("context").toUtf8();
00878         }
00879         else
00880         {
00881             textNode = element.namedItem("Text");
00882             if (textNode.isElement())
00883             {
00884                 QDomElement textElement = textNode.toElement();
00885                 text = textElement.text().toUtf8();
00886                 context = textElement.attribute("context").toUtf8();
00887             }
00888         }
00889 
00890         QString i18nText;
00891         if (!text.isEmpty() && !context.isEmpty())
00892             i18nText = i18nc(context, text);
00893         else if (!text.isEmpty())
00894             i18nText = i18n(text);
00895 
00896         if (!i18nText.isEmpty())
00897             setWindowTitle(i18nText);
00898     }
00899 
00900     /*
00901       This method is called in order to load toolbar settings from XML.
00902       However this can be used in two rather different cases:
00903       - for the initial loading of the app's XML. In that case the settings
00904       are only the defaults (Level_AppXML), the user's KConfig settings will override them
00905 
00906       - for later re-loading when switching between parts in KXMLGUIFactory.
00907       In that case the XML contains the final settings, not the defaults.
00908       We do need the defaults, and the toolbar might have been completely
00909       deleted and recreated meanwhile. So we store the app-default settings
00910       into the XML.
00911     */
00912     bool loadingAppDefaults = true;
00913     if (element.hasAttribute("tempXml")) {
00914         // this isn't the first time, so the app-xml defaults have been saved into the (in-memory) XML
00915         loadingAppDefaults = false;
00916         const QString iconSizeDefault = element.attribute("iconSizeDefault");
00917         if (!iconSizeDefault.isEmpty()) {
00918             d->iconSizeSettings[Level_AppXML] = iconSizeDefault.toInt();
00919         }
00920         const QString toolButtonStyleDefault = element.attribute("toolButtonStyleDefault");
00921         if (!toolButtonStyleDefault.isEmpty()) {
00922             d->toolButtonStyleSettings[Level_AppXML] = d->toolButtonStyleFromString(toolButtonStyleDefault);
00923         }
00924     } else {
00925         // loading app defaults
00926         bool newLine = false;
00927         QString attrNewLine = element.attribute("newline").toLower();
00928         if (!attrNewLine.isEmpty())
00929             newLine = attrNewLine == "true";
00930         if (newLine && mw)
00931             mw->insertToolBarBreak(this);
00932     }
00933 
00934     int newIconSize = -1;
00935     if (element.hasAttribute("iconSize")) {
00936         bool ok;
00937         newIconSize = element.attribute("iconSize").trimmed().toInt(&ok);
00938         if (!ok)
00939             newIconSize = -1;
00940     }
00941     if (newIconSize != -1)
00942         d->iconSizeSettings[loadingAppDefaults ? Level_AppXML : Level_UserSettings] = newIconSize;
00943 
00944     const QString newToolButtonStyle = element.attribute("iconText");
00945     if (!newToolButtonStyle.isEmpty())
00946         d->toolButtonStyleSettings[loadingAppDefaults ? Level_AppXML : Level_UserSettings] = d->toolButtonStyleFromString(newToolButtonStyle);
00947 
00948     bool hidden = false;
00949     {
00950         QString attrHidden = element.attribute("hidden").toLower();
00951         if (!attrHidden.isEmpty())
00952             hidden = attrHidden  == "true";
00953     }
00954 
00955     Qt::ToolBarArea pos = Qt::NoToolBarArea;
00956     {
00957         QString attrPosition = element.attribute("position").toLower();
00958         if (!attrPosition.isEmpty())
00959             pos = KToolBar::Private::positionFromString(attrPosition);
00960     }
00961     if (pos != Qt::NoToolBarArea)
00962         mw->addToolBar(pos, this);
00963 
00964     setVisible(!hidden);
00965 
00966     d->applyCurrentSettings();
00967 }
00968 
00969 // Called when switching between xmlgui clients, in order to find any unsaved settings
00970 // again when switching back to the current xmlgui client.
00971 void KToolBar::saveState(QDomElement &current) const
00972 {
00973     Q_ASSERT(!current.isNull());
00974 
00975     current.setAttribute("tempXml", "true");
00976 
00977     current.setAttribute("noMerge", "1");
00978     current.setAttribute("position", d->getPositionAsString().toLower());
00979     current.setAttribute("hidden", isHidden() ? "true" : "false");
00980 
00981     const int currentIconSize = iconSize().width();
00982     if (currentIconSize == d->iconSizeSettings.defaultValue())
00983         current.removeAttribute("iconSize");
00984     else
00985         current.setAttribute("iconSize", iconSize().width());
00986 
00987     if (toolButtonStyle() == d->toolButtonStyleSettings.defaultValue())
00988         current.removeAttribute("iconText");
00989     else
00990         current.setAttribute("iconText", d->toolButtonStyleToString(toolButtonStyle()));
00991 
00992     // Note: if this method is used by more than KXMLGUIBuilder, e.g. to save XML settings to *disk*,
00993     // then the stuff below shouldn't always be done. This is not the case currently though.
00994     if (d->iconSizeSettings[Level_AppXML] != Unset) {
00995         current.setAttribute("iconSizeDefault", d->iconSizeSettings[Level_AppXML]);
00996     }
00997     if (d->toolButtonStyleSettings[Level_AppXML] != Unset) {
00998         const Qt::ToolButtonStyle bs = static_cast<Qt::ToolButtonStyle>(d->toolButtonStyleSettings[Level_AppXML]);
00999         current.setAttribute("toolButtonStyleDefault", d->toolButtonStyleToString(bs));
01000     }
01001 }
01002 
01003 // called by KMainWindow::applyMainWindowSettings to read from the user settings
01004 void KToolBar::applySettings(const KConfigGroup &cg, bool forceGlobal)
01005 {
01006     Q_ASSERT(!cg.name().isEmpty());
01007     Q_UNUSED(forceGlobal); // KDE5: remove
01008 
01009     // a small leftover from kde3: separate bool for hidden/shown. But it's also part of saveMainWindowSettings,
01010     // it is not really useful anymore, except in the unlikely case where someone would call this by hand.
01011     // KDE5: remove the block below
01012     if (cg.hasKey("Hidden")) {
01013         const bool hidden = cg.readEntry("Hidden", false);
01014         if (hidden)
01015             hide();
01016         else {
01017             show();
01018         }
01019     }
01020 
01021     if (cg.hasKey("IconSize")) {
01022         d->iconSizeSettings[Level_UserSettings] = cg.readEntry("IconSize", 0);
01023     }
01024     if (cg.hasKey("ToolButtonStyle")) {
01025         d->toolButtonStyleSettings[Level_UserSettings] = d->toolButtonStyleFromString(cg.readEntry("ToolButtonStyle", QString()));
01026     }
01027 
01028     d->applyCurrentSettings();
01029 }
01030 
01031 KMainWindow * KToolBar::mainWindow() const
01032 {
01033   return qobject_cast<KMainWindow*>(const_cast<QObject*>(parent()));
01034 }
01035 
01036 void KToolBar::setIconDimensions(int size)
01037 {
01038     QToolBar::setIconSize(QSize(size, size));
01039     d->iconSizeSettings[Level_UserSettings] = size;
01040 }
01041 
01042 int KToolBar::iconSizeDefault() const
01043 {
01044     return KIconLoader::global()->currentSize(d->isMainToolBar ? KIconLoader::MainToolbar : KIconLoader::Toolbar);
01045 }
01046 
01047 void KToolBar::slotMovableChanged(bool movable)
01048 {
01049   if (movable && !KAuthorized::authorize("movable_toolbars"))
01050     setMovable(false);
01051 }
01052 
01053 void KToolBar::dragEnterEvent(QDragEnterEvent *event)
01054 {
01055   if (toolBarsEditable() && event->proposedAction() & (Qt::CopyAction | Qt::MoveAction) &&
01056        event->mimeData()->hasFormat("application/x-kde-action-list")) {
01057     QByteArray data = event->mimeData()->data("application/x-kde-action-list");
01058 
01059     QDataStream stream(data);
01060 
01061     QStringList actionNames;
01062 
01063     stream >> actionNames;
01064 
01065     foreach (const QString& actionName, actionNames) {
01066       foreach (KActionCollection* ac, KActionCollection::allCollections()) {
01067         QAction* newAction = ac->action(actionName.toAscii().constData());
01068         if (newAction) {
01069           d->actionsBeingDragged.append(newAction);
01070           break;
01071         }
01072       }
01073     }
01074 
01075     if (d->actionsBeingDragged.count()) {
01076       QAction* overAction = actionAt(event->pos());
01077 
01078       QFrame* dropIndicatorWidget = new QFrame(this);
01079       dropIndicatorWidget->resize(8, height() - 4);
01080       dropIndicatorWidget->setFrameShape(QFrame::VLine);
01081       dropIndicatorWidget->setLineWidth(3);
01082 
01083       d->dropIndicatorAction = insertWidget(overAction, dropIndicatorWidget);
01084 
01085       insertAction(overAction, d->dropIndicatorAction);
01086 
01087       event->acceptProposedAction();
01088       return;
01089     }
01090   }
01091 
01092   QToolBar::dragEnterEvent(event);
01093 }
01094 
01095 void KToolBar::dragMoveEvent(QDragMoveEvent *event)
01096 {
01097   if (toolBarsEditable())
01098     forever {
01099       if (d->dropIndicatorAction) {
01100         QAction* overAction = 0L;
01101         foreach (QAction* action, actions()) {
01102           // want to make it feel that half way across an action you're dropping on the other side of it
01103           QWidget* widget = widgetForAction(action);
01104           if (event->pos().x() < widget->pos().x() + (widget->width() / 2)) {
01105             overAction = action;
01106             break;
01107           }
01108         }
01109 
01110         if (overAction != d->dropIndicatorAction) {
01111           // Check to see if the indicator is already in the right spot
01112           int dropIndicatorIndex = actions().indexOf(d->dropIndicatorAction);
01113           if (dropIndicatorIndex + 1 < actions().count()) {
01114             if (actions()[ dropIndicatorIndex + 1 ] == overAction)
01115               break;
01116           } else if (!overAction) {
01117             break;
01118           }
01119 
01120           insertAction(overAction, d->dropIndicatorAction);
01121         }
01122 
01123         event->accept();
01124         return;
01125       }
01126       break;
01127     }
01128 
01129   QToolBar::dragMoveEvent(event);
01130 }
01131 
01132 void KToolBar::dragLeaveEvent(QDragLeaveEvent *event)
01133 {
01134   // Want to clear this even if toolBarsEditable was changed mid-drag (unlikey)
01135   delete d->dropIndicatorAction;
01136   d->dropIndicatorAction = 0L;
01137   d->actionsBeingDragged.clear();
01138 
01139   if (toolBarsEditable()) {
01140     event->accept();
01141     return;
01142   }
01143 
01144   QToolBar::dragLeaveEvent(event);
01145 }
01146 
01147 void KToolBar::dropEvent(QDropEvent *event)
01148 {
01149   if (toolBarsEditable()) {
01150     foreach (QAction* action, d->actionsBeingDragged) {
01151       if (actions().contains(action))
01152         removeAction(action);
01153       insertAction(d->dropIndicatorAction, action);
01154     }
01155   }
01156 
01157   // Want to clear this even if toolBarsEditable was changed mid-drag (unlikey)
01158   delete d->dropIndicatorAction;
01159   d->dropIndicatorAction = 0L;
01160   d->actionsBeingDragged.clear();
01161 
01162   if (toolBarsEditable()) {
01163     event->accept();
01164     return;
01165   }
01166 
01167   QToolBar::dropEvent(event);
01168 }
01169 
01170 void KToolBar::mousePressEvent(QMouseEvent *event)
01171 {
01172   if (toolBarsEditable() && event->button() == Qt::LeftButton) {
01173     if (KAction* action = qobject_cast<KAction*>(actionAt(event->pos()))) {
01174       d->dragAction = action;
01175       d->dragStartPosition = event->pos();
01176       event->accept();
01177       return;
01178     }
01179   }
01180 
01181   QToolBar::mousePressEvent(event);
01182 }
01183 
01184 void KToolBar::mouseMoveEvent(QMouseEvent *event)
01185 {
01186   if (!toolBarsEditable() || !d->dragAction)
01187     return QToolBar::mouseMoveEvent(event);
01188 
01189   if ((event->pos() - d->dragStartPosition).manhattanLength() < QApplication::startDragDistance()) {
01190     event->accept();
01191     return;
01192   }
01193 
01194   QDrag *drag = new QDrag(this);
01195   QMimeData *mimeData = new QMimeData;
01196 
01197   QByteArray data;
01198   {
01199     QDataStream stream(&data, QIODevice::WriteOnly);
01200 
01201     QStringList actionNames;
01202     actionNames << d->dragAction->objectName();
01203 
01204     stream << actionNames;
01205   }
01206 
01207   mimeData->setData("application/x-kde-action-list", data);
01208 
01209   drag->setMimeData(mimeData);
01210 
01211   Qt::DropAction dropAction = drag->start(Qt::MoveAction);
01212 
01213   if (dropAction == Qt::MoveAction)
01214     // Only remove from this toolbar if it was moved to another toolbar
01215     // Otherwise the receiver moves it.
01216     if (drag->target() != this)
01217       removeAction(d->dragAction);
01218 
01219   d->dragAction = 0L;
01220   event->accept();
01221 }
01222 
01223 void KToolBar::mouseReleaseEvent(QMouseEvent *event)
01224 {
01225   // Want to clear this even if toolBarsEditable was changed mid-drag (unlikey)
01226   if (d->dragAction) {
01227     d->dragAction = 0L;
01228     event->accept();
01229     return;
01230   }
01231 
01232   QToolBar::mouseReleaseEvent(event);
01233 }
01234 
01235 bool KToolBar::eventFilter(QObject * watched, QEvent * event)
01236 {
01237     // Generate context menu events for disabled buttons too...
01238     if (event->type() == QEvent::MouseButtonPress) {
01239         QMouseEvent* me = static_cast<QMouseEvent*>(event);
01240         if (me->buttons() & Qt::RightButton)
01241             if (QWidget* ww = qobject_cast<QWidget*>(watched))
01242                 if (ww->parent() == this && !ww->isEnabled())
01243                     QCoreApplication::postEvent(this, new QContextMenuEvent(QContextMenuEvent::Mouse, me->pos(), me->globalPos()));
01244 
01245     } else if (event->type() == QEvent::ParentChange) {
01246         // Make sure we're not leaving stale event filters around,
01247         // when a child is reparented somewhere else
01248         if (QWidget* ww = qobject_cast<QWidget*>(watched)) {
01249             if (!this->isAncestorOf(ww)) {
01250                 // New parent is not a subwidget - remove event filter
01251                 ww->removeEventFilter(this);
01252                 foreach (QWidget* child, ww->findChildren<QWidget*>())
01253                     child->removeEventFilter(this);
01254             }
01255         }
01256     }
01257 
01258     QToolButton* tb;
01259     if ((tb = qobject_cast<QToolButton*>(watched))) {
01260         const QList<QAction*> tbActions = tb->actions();
01261         if (!tbActions.isEmpty()) {
01262             // Handle MMB on toolbar buttons
01263             if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) {
01264                 QMouseEvent* me = static_cast<QMouseEvent*>(event);
01265                 if (me->button() == Qt::MidButton /*&&
01266                                                  act->receivers(SIGNAL(triggered(Qt::MouseButtons,Qt::KeyboardModifiers)))*/) {
01267                     QAction* act = tbActions.first();
01268                     if (me->type() == QEvent::MouseButtonPress)
01269                         tb->setDown(act->isEnabled());
01270                     else {
01271                         tb->setDown(false);
01272                         if (act->isEnabled()) {
01273                             QMetaObject::invokeMethod(act, "triggered", Qt::DirectConnection,
01274                                                       Q_ARG(Qt::MouseButtons, me->button()),
01275                                                       Q_ARG(Qt::KeyboardModifiers, QApplication::keyboardModifiers()));
01276                         }
01277                     }
01278                 }
01279             }
01280 
01281             // CJK languages use more verbose accelerator marker: they add a Latin
01282             // letter in parenthesis, and put accelerator on that. Hence, the default
01283             // removal of ampersand only may not be enough there, instead the whole
01284             // parenthesis construct should be removed. Use KLocale's method to do this.
01285             if (event->type() == QEvent::Show || event->type() == QEvent::Paint || event->type() == QEvent::EnabledChange) {
01286                 QAction *act = tb->defaultAction();
01287                 if (act) {
01288                     const QString text = KGlobal::locale()->removeAcceleratorMarker(act->iconText().isEmpty() ? act->text() : act->iconText());
01289                     const QString toolTip = KGlobal::locale()->removeAcceleratorMarker(act->toolTip());
01290                     // Filtering messages requested by translators (scripting).
01291                     tb->setText(i18nc("@action:intoolbar Text label of toolbar button", "%1", text));
01292                     tb->setToolTip(i18nc("@info:tooltip Tooltip of toolbar button", "%1", toolTip));
01293                 }
01294             }
01295         }
01296     }
01297 
01298     // Redirect mouse events to the toolbar when drag + drop editing is enabled
01299     if (toolBarsEditable()) {
01300         if (QWidget* ww = qobject_cast<QWidget*>(watched)) {
01301             switch (event->type()) {
01302             case QEvent::MouseButtonPress: {
01303                 QMouseEvent* me = static_cast<QMouseEvent*>(event);
01304                 QMouseEvent newEvent(me->type(), mapFromGlobal(ww->mapToGlobal(me->pos())), me->globalPos(),
01305                                       me->button(), me->buttons(), me->modifiers());
01306                 mousePressEvent(&newEvent);
01307                 return true;
01308             }
01309             case QEvent::MouseMove: {
01310                 QMouseEvent* me = static_cast<QMouseEvent*>(event);
01311                 QMouseEvent newEvent(me->type(), mapFromGlobal(ww->mapToGlobal(me->pos())), me->globalPos(),
01312                                       me->button(), me->buttons(), me->modifiers());
01313                 mouseMoveEvent(&newEvent);
01314                 return true;
01315             }
01316             case QEvent::MouseButtonRelease: {
01317                 QMouseEvent* me = static_cast<QMouseEvent*>(event);
01318                 QMouseEvent newEvent(me->type(), mapFromGlobal(ww->mapToGlobal(me->pos())), me->globalPos(),
01319                                       me->button(), me->buttons(), me->modifiers());
01320                 mouseReleaseEvent(&newEvent);
01321                 return true;
01322             }
01323             default:
01324                 break;
01325             }
01326         }
01327     }
01328 
01329     return QToolBar::eventFilter(watched, event);
01330 }
01331 
01332 void KToolBar::actionEvent(QActionEvent * event)
01333 {
01334   if (event->type() == QEvent::ActionRemoved) {
01335     QWidget* widget = widgetForAction(event->action());
01336     if (widget) {
01337         widget->removeEventFilter(this);
01338 
01339         foreach (QWidget* child, widget->findChildren<QWidget*>())
01340             child->removeEventFilter(this);
01341     }
01342   }
01343 
01344   QToolBar::actionEvent(event);
01345 
01346   if (event->type() == QEvent::ActionAdded) {
01347     QWidget* widget = widgetForAction(event->action());
01348     if (widget) {
01349         widget->installEventFilter(this);
01350 
01351         foreach (QWidget* child, widget->findChildren<QWidget*>())
01352             child->installEventFilter(this);
01353         // Center widgets that do not have any use for more space. See bug 165274
01354         if (!(widget->sizePolicy().horizontalPolicy() & QSizePolicy::GrowFlag)
01355             // ... but do not center when using text besides icon in vertical toolbar. See bug 243196
01356             && !(orientation() == Qt::Vertical && toolButtonStyle() == Qt::ToolButtonTextBesideIcon)) {
01357             const int index = layout()->indexOf(widget);
01358             if (index != -1) {
01359                 layout()->itemAt(index)->setAlignment(Qt::AlignJustify);
01360             }
01361         }
01362     }
01363   }
01364 
01365   d->adjustSeparatorVisibility();
01366 }
01367 
01368 bool KToolBar::toolBarsEditable()
01369 {
01370     return KToolBar::Private::s_editable;
01371 }
01372 
01373 void KToolBar::setToolBarsEditable(bool editable)
01374 {
01375     if (KToolBar::Private::s_editable != editable) {
01376         KToolBar::Private::s_editable = editable;
01377     }
01378 }
01379 
01380 void KToolBar::setToolBarsLocked(bool locked)
01381 {
01382     if (KToolBar::Private::s_locked != locked) {
01383         KToolBar::Private::s_locked = locked;
01384 
01385         foreach (KMainWindow* mw, KMainWindow::memberList()) {
01386             foreach (KToolBar* toolbar, mw->findChildren<KToolBar*>()) {
01387                 toolbar->d->setLocked(locked);
01388             }
01389         }
01390     }
01391 }
01392 
01393 bool KToolBar::toolBarsLocked()
01394 {
01395     return KToolBar::Private::s_locked;
01396 }
01397 
01398 #include "ktoolbar.moc"

KDEUI

Skip menu "KDEUI"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.5
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal