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(i18nc("Toolbar orientation", "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::removeXMLGUIClient( KXMLGUIClient *client ) 00868 { 00869 d->xmlguiClients.remove(client); 00870 } 00871 00872 void KToolBar::contextMenuEvent(QContextMenuEvent* event) 00873 { 00874 #ifndef KDE_NO_DEPRECATED 00875 if (mainWindow() && d->enableContext) { 00876 QPointer<KToolBar> guard(this); 00877 const QPoint globalPos = event->globalPos(); 00878 d->contextMenu(globalPos)->exec(globalPos); 00879 00880 // "Configure Toolbars" recreates toolbars, so we might not exist anymore. 00881 if (guard) { 00882 d->slotContextAboutToHide(); 00883 } 00884 return; 00885 } 00886 #endif 00887 00888 QToolBar::contextMenuEvent(event); 00889 } 00890 00891 Qt::ToolButtonStyle KToolBar::toolButtonStyleSetting() 00892 { 00893 KConfigGroup group(KGlobal::config(), "Toolbar style"); 00894 const QString fallback = Private::toolButtonStyleToString(Qt::ToolButtonTextBesideIcon); 00895 return KToolBar::Private::toolButtonStyleFromString(group.readEntry("ToolButtonStyle", fallback)); 00896 } 00897 00898 void KToolBar::loadState(const QDomElement &element) 00899 { 00900 QMainWindow *mw = mainWindow(); 00901 if (!mw) 00902 return; 00903 00904 { 00905 QDomNode textNode = element.namedItem("text"); 00906 QByteArray text; 00907 QByteArray context; 00908 if (textNode.isElement()) 00909 { 00910 QDomElement textElement = textNode.toElement(); 00911 text = textElement.text().toUtf8(); 00912 context = textElement.attribute("context").toUtf8(); 00913 } 00914 else 00915 { 00916 textNode = element.namedItem("Text"); 00917 if (textNode.isElement()) 00918 { 00919 QDomElement textElement = textNode.toElement(); 00920 text = textElement.text().toUtf8(); 00921 context = textElement.attribute("context").toUtf8(); 00922 } 00923 } 00924 00925 QString i18nText; 00926 if (!text.isEmpty() && !context.isEmpty()) 00927 i18nText = i18nc(context, text); 00928 else if (!text.isEmpty()) 00929 i18nText = i18n(text); 00930 00931 if (!i18nText.isEmpty()) 00932 setWindowTitle(i18nText); 00933 } 00934 00935 /* 00936 This method is called in order to load toolbar settings from XML. 00937 However this can be used in two rather different cases: 00938 - for the initial loading of the app's XML. In that case the settings 00939 are only the defaults (Level_AppXML), the user's KConfig settings will override them 00940 00941 - for later re-loading when switching between parts in KXMLGUIFactory. 00942 In that case the XML contains the final settings, not the defaults. 00943 We do need the defaults, and the toolbar might have been completely 00944 deleted and recreated meanwhile. So we store the app-default settings 00945 into the XML. 00946 */ 00947 bool loadingAppDefaults = true; 00948 if (element.hasAttribute("tempXml")) { 00949 // this isn't the first time, so the app-xml defaults have been saved into the (in-memory) XML 00950 loadingAppDefaults = false; 00951 const QString iconSizeDefault = element.attribute("iconSizeDefault"); 00952 if (!iconSizeDefault.isEmpty()) { 00953 d->iconSizeSettings[Level_AppXML] = iconSizeDefault.toInt(); 00954 } 00955 const QString toolButtonStyleDefault = element.attribute("toolButtonStyleDefault"); 00956 if (!toolButtonStyleDefault.isEmpty()) { 00957 d->toolButtonStyleSettings[Level_AppXML] = d->toolButtonStyleFromString(toolButtonStyleDefault); 00958 } 00959 } else { 00960 // loading app defaults 00961 bool newLine = false; 00962 QString attrNewLine = element.attribute("newline").toLower(); 00963 if (!attrNewLine.isEmpty()) 00964 newLine = attrNewLine == "true"; 00965 if (newLine && mw) 00966 mw->insertToolBarBreak(this); 00967 } 00968 00969 int newIconSize = -1; 00970 if (element.hasAttribute("iconSize")) { 00971 bool ok; 00972 newIconSize = element.attribute("iconSize").trimmed().toInt(&ok); 00973 if (!ok) 00974 newIconSize = -1; 00975 } 00976 if (newIconSize != -1) 00977 d->iconSizeSettings[loadingAppDefaults ? Level_AppXML : Level_UserSettings] = newIconSize; 00978 00979 const QString newToolButtonStyle = element.attribute("iconText"); 00980 if (!newToolButtonStyle.isEmpty()) 00981 d->toolButtonStyleSettings[loadingAppDefaults ? Level_AppXML : Level_UserSettings] = d->toolButtonStyleFromString(newToolButtonStyle); 00982 00983 bool hidden = false; 00984 { 00985 QString attrHidden = element.attribute("hidden").toLower(); 00986 if (!attrHidden.isEmpty()) 00987 hidden = attrHidden == "true"; 00988 } 00989 00990 Qt::ToolBarArea pos = Qt::NoToolBarArea; 00991 { 00992 QString attrPosition = element.attribute("position").toLower(); 00993 if (!attrPosition.isEmpty()) 00994 pos = KToolBar::Private::positionFromString(attrPosition); 00995 } 00996 if (pos != Qt::NoToolBarArea) 00997 mw->addToolBar(pos, this); 00998 00999 setVisible(!hidden); 01000 01001 d->applyCurrentSettings(); 01002 } 01003 01004 // Called when switching between xmlgui clients, in order to find any unsaved settings 01005 // again when switching back to the current xmlgui client. 01006 void KToolBar::saveState(QDomElement ¤t) const 01007 { 01008 Q_ASSERT(!current.isNull()); 01009 01010 current.setAttribute("tempXml", "true"); 01011 01012 current.setAttribute("noMerge", "1"); 01013 current.setAttribute("position", d->getPositionAsString().toLower()); 01014 current.setAttribute("hidden", isHidden() ? "true" : "false"); 01015 01016 const int currentIconSize = iconSize().width(); 01017 if (currentIconSize == d->iconSizeSettings.defaultValue()) 01018 current.removeAttribute("iconSize"); 01019 else 01020 current.setAttribute("iconSize", iconSize().width()); 01021 01022 if (toolButtonStyle() == d->toolButtonStyleSettings.defaultValue()) 01023 current.removeAttribute("iconText"); 01024 else 01025 current.setAttribute("iconText", d->toolButtonStyleToString(toolButtonStyle())); 01026 01027 // Note: if this method is used by more than KXMLGUIBuilder, e.g. to save XML settings to *disk*, 01028 // then the stuff below shouldn't always be done. This is not the case currently though. 01029 if (d->iconSizeSettings[Level_AppXML] != Unset) { 01030 current.setAttribute("iconSizeDefault", d->iconSizeSettings[Level_AppXML]); 01031 } 01032 if (d->toolButtonStyleSettings[Level_AppXML] != Unset) { 01033 const Qt::ToolButtonStyle bs = static_cast<Qt::ToolButtonStyle>(d->toolButtonStyleSettings[Level_AppXML]); 01034 current.setAttribute("toolButtonStyleDefault", d->toolButtonStyleToString(bs)); 01035 } 01036 } 01037 01038 // called by KMainWindow::applyMainWindowSettings to read from the user settings 01039 void KToolBar::applySettings(const KConfigGroup &cg, bool forceGlobal) 01040 { 01041 Q_ASSERT(!cg.name().isEmpty()); 01042 Q_UNUSED(forceGlobal); // KDE5: remove 01043 01044 // a small leftover from kde3: separate bool for hidden/shown. But it's also part of saveMainWindowSettings, 01045 // it is not really useful anymore, except in the unlikely case where someone would call this by hand. 01046 // KDE5: remove the block below 01047 if (cg.hasKey("Hidden")) { 01048 const bool hidden = cg.readEntry("Hidden", false); 01049 if (hidden) 01050 hide(); 01051 else { 01052 show(); 01053 } 01054 } 01055 01056 if (cg.hasKey("IconSize")) { 01057 d->iconSizeSettings[Level_UserSettings] = cg.readEntry("IconSize", 0); 01058 } 01059 if (cg.hasKey("ToolButtonStyle")) { 01060 d->toolButtonStyleSettings[Level_UserSettings] = d->toolButtonStyleFromString(cg.readEntry("ToolButtonStyle", QString())); 01061 } 01062 01063 d->applyCurrentSettings(); 01064 } 01065 01066 KMainWindow * KToolBar::mainWindow() const 01067 { 01068 return qobject_cast<KMainWindow*>(const_cast<QObject*>(parent())); 01069 } 01070 01071 void KToolBar::setIconDimensions(int size) 01072 { 01073 QToolBar::setIconSize(QSize(size, size)); 01074 d->iconSizeSettings[Level_UserSettings] = size; 01075 } 01076 01077 int KToolBar::iconSizeDefault() const 01078 { 01079 return KIconLoader::global()->currentSize(d->isMainToolBar ? KIconLoader::MainToolbar : KIconLoader::Toolbar); 01080 } 01081 01082 void KToolBar::slotMovableChanged(bool movable) 01083 { 01084 if (movable && !KAuthorized::authorize("movable_toolbars")) 01085 setMovable(false); 01086 } 01087 01088 void KToolBar::dragEnterEvent(QDragEnterEvent *event) 01089 { 01090 if (toolBarsEditable() && event->proposedAction() & (Qt::CopyAction | Qt::MoveAction) && 01091 event->mimeData()->hasFormat("application/x-kde-action-list")) { 01092 QByteArray data = event->mimeData()->data("application/x-kde-action-list"); 01093 01094 QDataStream stream(data); 01095 01096 QStringList actionNames; 01097 01098 stream >> actionNames; 01099 01100 foreach (const QString& actionName, actionNames) { 01101 foreach (KActionCollection* ac, KActionCollection::allCollections()) { 01102 QAction* newAction = ac->action(actionName.toAscii().constData()); 01103 if (newAction) { 01104 d->actionsBeingDragged.append(newAction); 01105 break; 01106 } 01107 } 01108 } 01109 01110 if (d->actionsBeingDragged.count()) { 01111 QAction* overAction = actionAt(event->pos()); 01112 01113 QFrame* dropIndicatorWidget = new QFrame(this); 01114 dropIndicatorWidget->resize(8, height() - 4); 01115 dropIndicatorWidget->setFrameShape(QFrame::VLine); 01116 dropIndicatorWidget->setLineWidth(3); 01117 01118 d->dropIndicatorAction = insertWidget(overAction, dropIndicatorWidget); 01119 01120 insertAction(overAction, d->dropIndicatorAction); 01121 01122 event->acceptProposedAction(); 01123 return; 01124 } 01125 } 01126 01127 QToolBar::dragEnterEvent(event); 01128 } 01129 01130 void KToolBar::dragMoveEvent(QDragMoveEvent *event) 01131 { 01132 if (toolBarsEditable()) 01133 forever { 01134 if (d->dropIndicatorAction) { 01135 QAction* overAction = 0L; 01136 foreach (QAction* action, actions()) { 01137 // want to make it feel that half way across an action you're dropping on the other side of it 01138 QWidget* widget = widgetForAction(action); 01139 if (event->pos().x() < widget->pos().x() + (widget->width() / 2)) { 01140 overAction = action; 01141 break; 01142 } 01143 } 01144 01145 if (overAction != d->dropIndicatorAction) { 01146 // Check to see if the indicator is already in the right spot 01147 int dropIndicatorIndex = actions().indexOf(d->dropIndicatorAction); 01148 if (dropIndicatorIndex + 1 < actions().count()) { 01149 if (actions()[ dropIndicatorIndex + 1 ] == overAction) 01150 break; 01151 } else if (!overAction) { 01152 break; 01153 } 01154 01155 insertAction(overAction, d->dropIndicatorAction); 01156 } 01157 01158 event->accept(); 01159 return; 01160 } 01161 break; 01162 } 01163 01164 QToolBar::dragMoveEvent(event); 01165 } 01166 01167 void KToolBar::dragLeaveEvent(QDragLeaveEvent *event) 01168 { 01169 // Want to clear this even if toolBarsEditable was changed mid-drag (unlikey) 01170 delete d->dropIndicatorAction; 01171 d->dropIndicatorAction = 0L; 01172 d->actionsBeingDragged.clear(); 01173 01174 if (toolBarsEditable()) { 01175 event->accept(); 01176 return; 01177 } 01178 01179 QToolBar::dragLeaveEvent(event); 01180 } 01181 01182 void KToolBar::dropEvent(QDropEvent *event) 01183 { 01184 if (toolBarsEditable()) { 01185 foreach (QAction* action, d->actionsBeingDragged) { 01186 if (actions().contains(action)) 01187 removeAction(action); 01188 insertAction(d->dropIndicatorAction, action); 01189 } 01190 } 01191 01192 // Want to clear this even if toolBarsEditable was changed mid-drag (unlikey) 01193 delete d->dropIndicatorAction; 01194 d->dropIndicatorAction = 0L; 01195 d->actionsBeingDragged.clear(); 01196 01197 if (toolBarsEditable()) { 01198 event->accept(); 01199 return; 01200 } 01201 01202 QToolBar::dropEvent(event); 01203 } 01204 01205 void KToolBar::mousePressEvent(QMouseEvent *event) 01206 { 01207 if (toolBarsEditable() && event->button() == Qt::LeftButton) { 01208 if (KAction* action = qobject_cast<KAction*>(actionAt(event->pos()))) { 01209 d->dragAction = action; 01210 d->dragStartPosition = event->pos(); 01211 event->accept(); 01212 return; 01213 } 01214 } 01215 01216 QToolBar::mousePressEvent(event); 01217 } 01218 01219 void KToolBar::mouseMoveEvent(QMouseEvent *event) 01220 { 01221 if (!toolBarsEditable() || !d->dragAction) 01222 return QToolBar::mouseMoveEvent(event); 01223 01224 if ((event->pos() - d->dragStartPosition).manhattanLength() < QApplication::startDragDistance()) { 01225 event->accept(); 01226 return; 01227 } 01228 01229 QDrag *drag = new QDrag(this); 01230 QMimeData *mimeData = new QMimeData; 01231 01232 QByteArray data; 01233 { 01234 QDataStream stream(&data, QIODevice::WriteOnly); 01235 01236 QStringList actionNames; 01237 actionNames << d->dragAction->objectName(); 01238 01239 stream << actionNames; 01240 } 01241 01242 mimeData->setData("application/x-kde-action-list", data); 01243 01244 drag->setMimeData(mimeData); 01245 01246 Qt::DropAction dropAction = drag->start(Qt::MoveAction); 01247 01248 if (dropAction == Qt::MoveAction) 01249 // Only remove from this toolbar if it was moved to another toolbar 01250 // Otherwise the receiver moves it. 01251 if (drag->target() != this) 01252 removeAction(d->dragAction); 01253 01254 d->dragAction = 0L; 01255 event->accept(); 01256 } 01257 01258 void KToolBar::mouseReleaseEvent(QMouseEvent *event) 01259 { 01260 // Want to clear this even if toolBarsEditable was changed mid-drag (unlikey) 01261 if (d->dragAction) { 01262 d->dragAction = 0L; 01263 event->accept(); 01264 return; 01265 } 01266 01267 QToolBar::mouseReleaseEvent(event); 01268 } 01269 01270 bool KToolBar::eventFilter(QObject * watched, QEvent * event) 01271 { 01272 // Generate context menu events for disabled buttons too... 01273 if (event->type() == QEvent::MouseButtonPress) { 01274 QMouseEvent* me = static_cast<QMouseEvent*>(event); 01275 if (me->buttons() & Qt::RightButton) 01276 if (QWidget* ww = qobject_cast<QWidget*>(watched)) 01277 if (ww->parent() == this && !ww->isEnabled()) 01278 QCoreApplication::postEvent(this, new QContextMenuEvent(QContextMenuEvent::Mouse, me->pos(), me->globalPos())); 01279 01280 } else if (event->type() == QEvent::ParentChange) { 01281 // Make sure we're not leaving stale event filters around, 01282 // when a child is reparented somewhere else 01283 if (QWidget* ww = qobject_cast<QWidget*>(watched)) { 01284 if (!this->isAncestorOf(ww)) { 01285 // New parent is not a subwidget - remove event filter 01286 ww->removeEventFilter(this); 01287 foreach (QWidget* child, ww->findChildren<QWidget*>()) 01288 child->removeEventFilter(this); 01289 } 01290 } 01291 } 01292 01293 QToolButton* tb; 01294 if ((tb = qobject_cast<QToolButton*>(watched))) { 01295 const QList<QAction*> tbActions = tb->actions(); 01296 if (!tbActions.isEmpty()) { 01297 // Handle MMB on toolbar buttons 01298 if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease) { 01299 QMouseEvent* me = static_cast<QMouseEvent*>(event); 01300 if (me->button() == Qt::MidButton /*&& 01301 act->receivers(SIGNAL(triggered(Qt::MouseButtons,Qt::KeyboardModifiers)))*/) { 01302 QAction* act = tbActions.first(); 01303 if (me->type() == QEvent::MouseButtonPress) 01304 tb->setDown(act->isEnabled()); 01305 else { 01306 tb->setDown(false); 01307 if (act->isEnabled()) { 01308 QMetaObject::invokeMethod(act, "triggered", Qt::DirectConnection, 01309 Q_ARG(Qt::MouseButtons, me->button()), 01310 Q_ARG(Qt::KeyboardModifiers, QApplication::keyboardModifiers())); 01311 } 01312 } 01313 } 01314 } 01315 01316 // CJK languages use more verbose accelerator marker: they add a Latin 01317 // letter in parenthesis, and put accelerator on that. Hence, the default 01318 // removal of ampersand only may not be enough there, instead the whole 01319 // parenthesis construct should be removed. Use KLocale's method to do this. 01320 if (event->type() == QEvent::Show || event->type() == QEvent::Paint || event->type() == QEvent::EnabledChange) { 01321 QAction *act = tb->defaultAction(); 01322 if (act) { 01323 const QString text = KGlobal::locale()->removeAcceleratorMarker(act->iconText().isEmpty() ? act->text() : act->iconText()); 01324 const QString toolTip = KGlobal::locale()->removeAcceleratorMarker(act->toolTip()); 01325 // Filtering messages requested by translators (scripting). 01326 tb->setText(i18nc("@action:intoolbar Text label of toolbar button", "%1", text)); 01327 tb->setToolTip(i18nc("@info:tooltip Tooltip of toolbar button", "%1", toolTip)); 01328 } 01329 } 01330 } 01331 } 01332 01333 // Redirect mouse events to the toolbar when drag + drop editing is enabled 01334 if (toolBarsEditable()) { 01335 if (QWidget* ww = qobject_cast<QWidget*>(watched)) { 01336 switch (event->type()) { 01337 case QEvent::MouseButtonPress: { 01338 QMouseEvent* me = static_cast<QMouseEvent*>(event); 01339 QMouseEvent newEvent(me->type(), mapFromGlobal(ww->mapToGlobal(me->pos())), me->globalPos(), 01340 me->button(), me->buttons(), me->modifiers()); 01341 mousePressEvent(&newEvent); 01342 return true; 01343 } 01344 case QEvent::MouseMove: { 01345 QMouseEvent* me = static_cast<QMouseEvent*>(event); 01346 QMouseEvent newEvent(me->type(), mapFromGlobal(ww->mapToGlobal(me->pos())), me->globalPos(), 01347 me->button(), me->buttons(), me->modifiers()); 01348 mouseMoveEvent(&newEvent); 01349 return true; 01350 } 01351 case QEvent::MouseButtonRelease: { 01352 QMouseEvent* me = static_cast<QMouseEvent*>(event); 01353 QMouseEvent newEvent(me->type(), mapFromGlobal(ww->mapToGlobal(me->pos())), me->globalPos(), 01354 me->button(), me->buttons(), me->modifiers()); 01355 mouseReleaseEvent(&newEvent); 01356 return true; 01357 } 01358 default: 01359 break; 01360 } 01361 } 01362 } 01363 01364 return QToolBar::eventFilter(watched, event); 01365 } 01366 01367 void KToolBar::actionEvent(QActionEvent * event) 01368 { 01369 if (event->type() == QEvent::ActionRemoved) { 01370 QWidget* widget = widgetForAction(event->action()); 01371 if (widget) { 01372 widget->removeEventFilter(this); 01373 01374 foreach (QWidget* child, widget->findChildren<QWidget*>()) 01375 child->removeEventFilter(this); 01376 } 01377 } 01378 01379 QToolBar::actionEvent(event); 01380 01381 if (event->type() == QEvent::ActionAdded) { 01382 QWidget* widget = widgetForAction(event->action()); 01383 if (widget) { 01384 widget->installEventFilter(this); 01385 01386 foreach (QWidget* child, widget->findChildren<QWidget*>()) 01387 child->installEventFilter(this); 01388 // Center widgets that do not have any use for more space. See bug 165274 01389 if (!(widget->sizePolicy().horizontalPolicy() & QSizePolicy::GrowFlag) 01390 // ... but do not center when using text besides icon in vertical toolbar. See bug 243196 01391 && !(orientation() == Qt::Vertical && toolButtonStyle() == Qt::ToolButtonTextBesideIcon)) { 01392 const int index = layout()->indexOf(widget); 01393 if (index != -1) { 01394 layout()->itemAt(index)->setAlignment(Qt::AlignJustify); 01395 } 01396 } 01397 } 01398 } 01399 01400 d->adjustSeparatorVisibility(); 01401 } 01402 01403 bool KToolBar::toolBarsEditable() 01404 { 01405 return KToolBar::Private::s_editable; 01406 } 01407 01408 void KToolBar::setToolBarsEditable(bool editable) 01409 { 01410 if (KToolBar::Private::s_editable != editable) { 01411 KToolBar::Private::s_editable = editable; 01412 } 01413 } 01414 01415 void KToolBar::setToolBarsLocked(bool locked) 01416 { 01417 if (KToolBar::Private::s_locked != locked) { 01418 KToolBar::Private::s_locked = locked; 01419 01420 foreach (KMainWindow* mw, KMainWindow::memberList()) { 01421 foreach (KToolBar* toolbar, mw->findChildren<KToolBar*>()) { 01422 toolbar->d->setLocked(locked); 01423 } 01424 } 01425 } 01426 } 01427 01428 bool KToolBar::toolBarsLocked() 01429 { 01430 return KToolBar::Private::s_locked; 01431 } 01432 01433 #include "ktoolbar.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:32:45 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:32:45 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.