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 ¤t) 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"
KDE 4.7 API Reference