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

KDE's Doxygen guidelines are available online.

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-4.8.3 API Reference

Skip menu "kdelibs-4.8.3 API Reference"
  • 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
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal