File indexing completed on 2024-04-14 14:29:55

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2009 David Faure <faure@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0006 */
0007 
0008 #include "testguiclient.h"
0009 #include "testxmlguiwindow.h"
0010 
0011 #ifdef QT_DBUS_LIB
0012 #include <QDBusConnection>
0013 #endif
0014 #include <QDir>
0015 #include <QFile>
0016 #include <QFileInfo>
0017 #include <QSignalSpy>
0018 #include <QStandardPaths>
0019 #include <QTest>
0020 
0021 #include <KConfig>
0022 #include <KConfigGroup>
0023 #include <KIconLoader>
0024 #include <KSharedConfig>
0025 #include <kmainwindow.h>
0026 #include <ktoolbar.h>
0027 
0028 // We use the data types below in a QVariant, so Q_DECLARE_METATYPE is needed for them.
0029 Q_DECLARE_METATYPE(Qt::MouseButton)
0030 Q_DECLARE_METATYPE(Qt::MouseButtons)
0031 Q_DECLARE_METATYPE(Qt::KeyboardModifiers)
0032 
0033 // Ensure everything uses test paths, including stuff run before main, such as the KdePlatformThemePlugin
0034 void enableTestMode()
0035 {
0036     QStandardPaths::setTestModeEnabled(true);
0037 }
0038 Q_CONSTRUCTOR_FUNCTION(enableTestMode)
0039 
0040 class tst_KToolBar : public QObject
0041 {
0042     Q_OBJECT
0043 
0044 public Q_SLOTS:
0045     void initTestCase();
0046     void cleanupTestCase();
0047     void init();
0048     void cleanup();
0049 
0050 private Q_SLOTS:
0051     void ktoolbar();
0052 
0053     void testIconSizeNoXmlGui_data();
0054     void testIconSizeNoXmlGui();
0055     void testIconSizeXmlGui_data();
0056     void testIconSizeXmlGui();
0057     void testToolButtonStyleNoXmlGui_data();
0058     void testToolButtonStyleNoXmlGui();
0059     void testToolButtonStyleXmlGui_data();
0060     void testToolButtonStyleXmlGui();
0061     void testToolBarPosition();
0062     void testXmlGuiSwitching();
0063     void testKAuthorizedDisableToggleAction();
0064 
0065 Q_SIGNALS:
0066     void signalAppearanceChanged();
0067 
0068 protected:
0069     bool eventFilter(QObject *watched, QEvent *event) override;
0070 
0071 private:
0072     void changeGlobalIconSizeSetting(int, int);
0073     void deleteGlobalIconSizeSetting();
0074     void changeGlobalToolButtonStyleSetting(const QString &, const QString &);
0075     void deleteGlobalToolButtonStyleSetting();
0076     QByteArray m_xml;
0077     bool m_showWasCalled;
0078 };
0079 
0080 QTEST_MAIN(tst_KToolBar)
0081 
0082 static void copy_dir(const QString &from, const QDir &to)
0083 {
0084     QDir src = QDir(from);
0085     QDir dest = QDir(to.filePath(src.dirName()));
0086     to.mkpath(src.dirName());
0087     const auto fileInfos = src.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
0088     for (const QFileInfo &fileInfo : fileInfos) {
0089         if (fileInfo.isDir()) {
0090             copy_dir(fileInfo.filePath(), dest);
0091         } else {
0092             QFile::copy(fileInfo.filePath(), dest.filePath(fileInfo.fileName()));
0093         }
0094     }
0095 }
0096 
0097 // This will be called before the first test function is executed.
0098 // It is only called once.
0099 void tst_KToolBar::initTestCase()
0100 {
0101     // start with a clean place to put data
0102     QDir testDataDir = QDir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
0103     QVERIFY(testDataDir.absolutePath().contains(QLatin1String("qttest")));
0104     testDataDir.removeRecursively();
0105     testDataDir.mkpath(QStringLiteral("."));
0106 
0107     // setup action restriction so we can test whether this actually disables some functionality
0108     KConfigGroup actionRestrictions(KSharedConfig::openConfig(), "KDE Action Restrictions");
0109     actionRestrictions.writeEntry("action/options_show_toolbar", false);
0110 
0111     // copy a minimal icon theme to where KIconTheme will find it, in case oxygen-icons is not
0112     // installed
0113     copy_dir(QFINDTESTDATA("icons"), testDataDir);
0114 
0115     m_xml =
0116         "<?xml version = '1.0'?>\n"
0117         "<!DOCTYPE gui SYSTEM \"kpartgui.dtd\">\n"
0118         "<gui version=\"1\" name=\"foo\" >\n"
0119         "<MenuBar>\n"
0120         "</MenuBar>\n"
0121         "<ToolBar name=\"mainToolBar\">\n"
0122         "  <Action name=\"go_up\"/>\n"
0123         "</ToolBar>\n"
0124         "<ToolBar name=\"otherToolBar\" position=\"bottom\" iconText=\"TextUnderIcon\">\n"
0125         "  <Action name=\"go_up\"/>\n"
0126         "</ToolBar>\n"
0127         "<ToolBar name=\"cleanToolBar\">\n"
0128         "  <Action name=\"go_up\"/>\n"
0129         "</ToolBar>\n"
0130         "<ToolBar name=\"hiddenToolBar\" hidden=\"true\">\n"
0131         "  <Action name=\"go_up\"/>\n"
0132         "</ToolBar>\n"
0133         "<ToolBar name=\"secondHiddenToolBar\" hidden=\"true\">\n"
0134         "  <Action name=\"go_up\"/>\n"
0135         "</ToolBar>\n"
0136         "<ToolBar iconSize=\"32\" name=\"bigToolBar\">\n"
0137         "  <Action name=\"go_up\"/>\n"
0138         "</ToolBar>\n"
0139         "<ToolBar iconSize=\"32\" name=\"bigUnchangedToolBar\">\n"
0140         "  <Action name=\"go_up\"/>\n"
0141         "</ToolBar>\n"
0142         "</gui>\n";
0143 
0144     qRegisterMetaType<Qt::MouseButtons>("Qt::MouseButtons");
0145     qRegisterMetaType<Qt::KeyboardModifiers>("Qt::KeyboardModifiers");
0146 }
0147 
0148 // This will be called after the last test function is executed.
0149 // It is only called once.
0150 void tst_KToolBar::cleanupTestCase()
0151 {
0152     QDir testDataDir = QDir(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
0153     QDir testIconsDir = QDir(testDataDir.absoluteFilePath(QStringLiteral("icons")));
0154     QVERIFY(testIconsDir.absolutePath().contains(QLatin1String("qttest")));
0155     testIconsDir.removeRecursively();
0156 }
0157 
0158 // This will be called before each test function is executed.
0159 void tst_KToolBar::init()
0160 {
0161 }
0162 
0163 // This will be called after every test function.
0164 void tst_KToolBar::cleanup()
0165 {
0166     QFile::remove(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QStringLiteral("/tst_KToolBar"));
0167     deleteGlobalIconSizeSetting();
0168     deleteGlobalToolButtonStyleSetting();
0169 }
0170 
0171 void tst_KToolBar::ktoolbar()
0172 {
0173     KMainWindow kmw;
0174     // Creating a KToolBar directly
0175     KToolBar bar(&kmw);
0176     QCOMPARE(bar.mainWindow(), &kmw);
0177     // Asking KMainWindow for a KToolBar (more common)
0178     KToolBar *mainToolBar = kmw.toolBar(QStringLiteral("mainToolBar"));
0179     QCOMPARE(mainToolBar->mainWindow(), &kmw);
0180 }
0181 
0182 Q_DECLARE_METATYPE(KConfigGroup)
0183 
0184 void tst_KToolBar::testIconSizeNoXmlGui_data()
0185 {
0186     QTest::addColumn<int>("iconSize");
0187     QTest::newRow("16") << 16;
0188     QTest::newRow("22") << 22;
0189     QTest::newRow("32") << 32;
0190     QTest::newRow("64") << 64;
0191 }
0192 
0193 void tst_KToolBar::testIconSizeNoXmlGui()
0194 {
0195     QFETCH(int, iconSize);
0196     KConfig config(QStringLiteral("tst_KToolBar"));
0197     KConfigGroup group(&config, "group");
0198     {
0199         KMainWindow kmw;
0200         KToolBar *mainToolBar = kmw.toolBar(QStringLiteral("mainToolBar"));
0201         KToolBar *otherToolBar = kmw.toolBar(QStringLiteral("otherToolBar"));
0202 
0203         // Default settings (applied by applyAppearanceSettings)
0204         QCOMPARE(mainToolBar->iconSize().width(), KIconLoader::global()->currentSize(KIconLoader::MainToolbar));
0205         QCOMPARE(otherToolBar->iconSize().width(), KIconLoader::global()->currentSize(KIconLoader::Toolbar));
0206         // check the actual values - update this if kicontheme's defaults are changed
0207         QCOMPARE(KIconLoader::global()->currentSize(KIconLoader::MainToolbar), 22);
0208         QCOMPARE(KIconLoader::global()->currentSize(KIconLoader::Toolbar), 22);
0209 
0210         // Changing settings for a given toolbar, as user
0211         mainToolBar->setIconDimensions(iconSize);
0212         otherToolBar->setIconDimensions(iconSize);
0213 
0214         // Save settings
0215         kmw.saveMainWindowSettings(group);
0216         // was it the default value?
0217         if (iconSize == KIconLoader::global()->currentSize(KIconLoader::MainToolbar)) {
0218             QCOMPARE(group.groupList().count(), 0); // nothing to save
0219             QVERIFY(!group.group("Toolbar mainToolBar").hasKey("IconSize"));
0220         } else {
0221             QCOMPARE(group.groupList().count(), 2); // two subgroups (one for each toolbar)
0222             QVERIFY(group.group("Toolbar mainToolBar").hasKey("IconSize"));
0223         }
0224     }
0225 
0226     {
0227         // Recreate, load, compare.
0228         KMainWindow kmw;
0229         KToolBar *mainToolBar = kmw.toolBar(QStringLiteral("mainToolBar"));
0230         KToolBar *otherToolBar = kmw.toolBar(QStringLiteral("otherToolBar"));
0231         KToolBar *cleanToolBar = kmw.toolBar(QStringLiteral("cleanToolBar"));
0232         QCOMPARE(mainToolBar->iconSize().width(), KIconLoader::global()->currentSize(KIconLoader::MainToolbar));
0233         QCOMPARE(otherToolBar->iconSize().width(), KIconLoader::global()->currentSize(KIconLoader::Toolbar));
0234         QCOMPARE(cleanToolBar->iconSize().width(), KIconLoader::global()->currentSize(KIconLoader::Toolbar));
0235         kmw.applyMainWindowSettings(group);
0236         QCOMPARE(mainToolBar->iconSize().width(), iconSize);
0237         QCOMPARE(otherToolBar->iconSize().width(), iconSize);
0238         QCOMPARE(cleanToolBar->iconSize().width(), KIconLoader::global()->currentSize(KIconLoader::Toolbar)); // unchanged
0239         const bool mainToolBarWasUsingDefaultSize = iconSize == KIconLoader::global()->currentSize(KIconLoader::MainToolbar);
0240         const bool otherToolBarWasUsingDefaultSize = iconSize == KIconLoader::global()->currentSize(KIconLoader::Toolbar);
0241 
0242 #ifndef Q_OS_WIN // the change notification uses DBus
0243         // Now emulate a change of the kde-global setting (#168480#c12)
0244         changeGlobalIconSizeSetting(32, 33);
0245 
0246         QCOMPARE(KIconLoader::global()->currentSize(KIconLoader::MainToolbar), 32);
0247         QCOMPARE(KIconLoader::global()->currentSize(KIconLoader::Toolbar), 33);
0248 
0249         if (mainToolBarWasUsingDefaultSize) {
0250             QCOMPARE(mainToolBar->iconSize().width(), 32);
0251         } else { // the user chose a specific size for the toolbar, so the new global size isn't used
0252             QCOMPARE(mainToolBar->iconSize().width(), iconSize);
0253         }
0254         if (otherToolBarWasUsingDefaultSize) {
0255             QCOMPARE(otherToolBar->iconSize().width(), 33);
0256         } else { // the user chose a specific size for the toolbar, so the new global size isn't used
0257             QCOMPARE(otherToolBar->iconSize().width(), iconSize);
0258         }
0259         QCOMPARE(cleanToolBar->iconSize().width(), 33);
0260 #endif
0261     }
0262 }
0263 
0264 void tst_KToolBar::testIconSizeXmlGui_data()
0265 {
0266     QTest::addColumn<int>("iconSize"); // set by user and saved to KConfig
0267     QTest::addColumn<int>("expectedSizeMainToolbar"); // ... after kde-global is changed to 25
0268     QTest::addColumn<int>("expectedSizeOtherToolbar"); // ... after kde-global is changed to 16
0269     QTest::addColumn<int>("expectedSizeCleanToolbar"); // ... after kde-global is changed to 16
0270     QTest::addColumn<int>("expectedSizeBigToolbar"); // ... after kde-global is changed to 16
0271     // When the user chose a specific size for the toolbar (!= its default size), the new kde-global size isn't applied to that toolbar.
0272     // So, only in case the toolbar was at iconSize already, and there was no setting in xml, we end up with kdeGlobal being used:
0273     const int kdeGlobalMain = 25;
0274     const int kdeGlobalOther = 16;
0275     QTest::newRow("16") << 16 << 16 << 16 << kdeGlobalOther << 16;
0276     QTest::newRow("22") << 22 << kdeGlobalMain << kdeGlobalOther << kdeGlobalOther << 22;
0277     QTest::newRow("32") << 32 << 32 << 32 << kdeGlobalOther << 32;
0278     QTest::newRow("64") << 64 << 64 << 64 << kdeGlobalOther << 64;
0279 }
0280 
0281 void tst_KToolBar::testIconSizeXmlGui()
0282 {
0283     QFETCH(int, iconSize);
0284     QFETCH(int, expectedSizeMainToolbar);
0285     QFETCH(int, expectedSizeOtherToolbar);
0286     QFETCH(int, expectedSizeCleanToolbar);
0287     QFETCH(int, expectedSizeBigToolbar);
0288     KConfig config(QStringLiteral("tst_KToolBar"));
0289     KConfigGroup group(&config, "group");
0290     {
0291         TestXmlGuiWindow kmw(m_xml, "tst_ktoolbar.rc");
0292         kmw.createActions(QStringList() << QStringLiteral("go_up"));
0293         kmw.createGUI();
0294         KToolBar *mainToolBar = kmw.toolBarByName(QStringLiteral("mainToolBar"));
0295         KToolBar *otherToolBar = kmw.toolBarByName(QStringLiteral("otherToolBar"));
0296         KToolBar *cleanToolBar = kmw.toolBarByName(QStringLiteral("cleanToolBar"));
0297         KToolBar *bigToolBar = kmw.toolBarByName(QStringLiteral("bigToolBar"));
0298         KToolBar *bigUnchangedToolBar = kmw.toolBarByName(QStringLiteral("bigUnchangedToolBar"));
0299 
0300         // Default settings (applied by applyAppearanceSettings)
0301         QCOMPARE(mainToolBar->iconSize().width(), KIconLoader::global()->currentSize(KIconLoader::MainToolbar));
0302         QCOMPARE(otherToolBar->iconSize().width(), KIconLoader::global()->currentSize(KIconLoader::Toolbar));
0303         // check the actual values - update this if kicontheme's defaults are changed
0304         QCOMPARE(mainToolBar->iconSize().width(), 22);
0305         QCOMPARE(otherToolBar->iconSize().width(), 22);
0306         QCOMPARE(cleanToolBar->iconSize().width(), 22);
0307         QCOMPARE(bigToolBar->iconSize().width(), 32);
0308         QCOMPARE(bigUnchangedToolBar->iconSize().width(), 32);
0309 
0310         // Changing settings for a given toolbar, as user (to test the initial report in #168480)
0311         mainToolBar->setIconDimensions(iconSize);
0312         otherToolBar->setIconDimensions(iconSize);
0313         bigToolBar->setIconDimensions(iconSize);
0314 
0315         // Save settings
0316         kmw.saveMainWindowSettings(group);
0317         // was it the default size? (for the main toolbar, we only check that one)
0318         const bool usingDefaultSize = iconSize == KIconLoader::global()->currentSize(KIconLoader::MainToolbar);
0319         if (usingDefaultSize) {
0320             QVERIFY(!group.groupList().contains(QLatin1String("Toolbar mainToolBar")));
0321             QVERIFY(!group.group("Toolbar mainToolBar").hasKey("IconSize"));
0322         } else {
0323             QVERIFY(group.group("Toolbar mainToolBar").hasKey("IconSize"));
0324         }
0325 
0326 #ifndef Q_OS_WIN // the change notification uses DBus
0327         // Now emulate a change of the kde-global setting (#168480#c12)
0328         changeGlobalIconSizeSetting(25, 16);
0329 
0330         QCOMPARE(mainToolBar->iconSize().width(), expectedSizeMainToolbar);
0331         QCOMPARE(otherToolBar->iconSize().width(), expectedSizeOtherToolbar);
0332         QCOMPARE(cleanToolBar->iconSize().width(), expectedSizeCleanToolbar);
0333         QCOMPARE(bigToolBar->iconSize().width(), expectedSizeBigToolbar);
0334 #endif
0335 
0336         // The big unchanged toolbar should be, well, unchanged; AppXml has priority over KDE_Default.
0337         QCOMPARE(bigUnchangedToolBar->iconSize().width(), 32);
0338     }
0339 }
0340 
0341 void tst_KToolBar::changeGlobalIconSizeSetting(int mainToolbarIconSize, int iconSize)
0342 {
0343     // We could use KConfig::Normal|KConfig::Global here, to write to kdeglobals like kcmstyle does,
0344     // but we don't need to. Writing to the app's config file works too.
0345     KConfigGroup mglobals(KSharedConfig::openConfig(), "MainToolbarIcons");
0346     mglobals.writeEntry("Size", mainToolbarIconSize);
0347     KConfigGroup globals(KSharedConfig::openConfig(), "ToolbarIcons");
0348     // globals.writeEntry("Size", iconSize, KConfig::Normal|KConfig::Global);
0349     globals.writeEntry("Size", iconSize);
0350     KSharedConfig::openConfig()->sync();
0351 
0352     QSignalSpy spy(KIconLoader::global(), &KIconLoader::iconChanged);
0353     KIconLoader::global()->emitChange(KIconLoader::Desktop);
0354     spy.wait(200);
0355 }
0356 
0357 void tst_KToolBar::deleteGlobalIconSizeSetting()
0358 {
0359     KConfigGroup mglobals(KSharedConfig::openConfig(), "MainToolbarIcons");
0360     mglobals.deleteEntry("Size");
0361     KConfigGroup globals(KSharedConfig::openConfig(), "ToolbarIcons");
0362     globals.deleteEntry("Size");
0363     KSharedConfig::openConfig()->sync();
0364 
0365     QSignalSpy spy(KIconLoader::global(), &KIconLoader::iconChanged);
0366     KIconLoader::global()->emitChange(KIconLoader::Desktop);
0367     spy.wait(200);
0368 }
0369 
0370 Q_DECLARE_METATYPE(Qt::ToolButtonStyle)
0371 
0372 void tst_KToolBar::testToolButtonStyleNoXmlGui_data()
0373 {
0374     QTest::addColumn<Qt::ToolButtonStyle>("toolButtonStyle");
0375     QTest::newRow("Qt::ToolButtonIconOnly") << Qt::ToolButtonIconOnly;
0376     QTest::newRow("Qt::ToolButtonTextOnly") << Qt::ToolButtonTextOnly;
0377     QTest::newRow("Qt::ToolButtonTextBesideIcon") << Qt::ToolButtonTextBesideIcon;
0378     QTest::newRow("Qt::ToolButtonTextUnderIcon") << Qt::ToolButtonTextUnderIcon;
0379 }
0380 
0381 void tst_KToolBar::testToolButtonStyleNoXmlGui()
0382 {
0383     QFETCH(Qt::ToolButtonStyle, toolButtonStyle);
0384     const Qt::ToolButtonStyle mainToolBarDefaultStyle = Qt::ToolButtonTextBesideIcon; // was TextUnderIcon before KDE-4.4.0
0385     const bool selectedDefaultForMainToolbar = toolButtonStyle == mainToolBarDefaultStyle;
0386     const bool selectedDefaultForOtherToolbar = toolButtonStyle == Qt::ToolButtonTextBesideIcon;
0387 
0388     KConfig config(QStringLiteral("tst_KToolBar"));
0389     KConfigGroup group(&config, "group");
0390     {
0391         KMainWindow kmw;
0392         KToolBar *mainToolBar = kmw.toolBar(QStringLiteral("mainToolBar"));
0393         KToolBar *otherToolBar = kmw.toolBar(QStringLiteral("otherToolBar"));
0394 
0395         // Default settings (applied by applyAppearanceSettings)
0396         QCOMPARE((int)mainToolBar->toolButtonStyle(), (int)mainToolBarDefaultStyle);
0397         QCOMPARE((int)otherToolBar->toolButtonStyle(), (int)Qt::ToolButtonTextBesideIcon); // see r883541
0398         QCOMPARE(kmw.toolBarArea(mainToolBar), Qt::TopToolBarArea);
0399 
0400         // Changing settings for a given toolbar, as user
0401         mainToolBar->setToolButtonStyle(toolButtonStyle);
0402         otherToolBar->setToolButtonStyle(toolButtonStyle);
0403 
0404         // Save settings
0405         kmw.saveMainWindowSettings(group);
0406         if (selectedDefaultForMainToolbar) {
0407             QCOMPARE(group.groupList().count(), 0); // nothing to save
0408             QVERIFY(!group.group("Toolbar mainToolBar").hasKey("ToolButtonStyle"));
0409         } else {
0410             QCOMPARE(group.groupList().count(), 2); // two subgroups (one for each toolbar)
0411             QVERIFY(group.group("Toolbar mainToolBar").hasKey("ToolButtonStyle"));
0412         }
0413     }
0414 
0415     {
0416         // Recreate, load, compare.
0417         KMainWindow kmw;
0418         KToolBar *mainToolBar = kmw.toolBar(QStringLiteral("mainToolBar"));
0419         KToolBar *otherToolBar = kmw.toolBar(QStringLiteral("otherToolBar"));
0420         QCOMPARE((int)mainToolBar->toolButtonStyle(), (int)mainToolBarDefaultStyle);
0421         kmw.applyMainWindowSettings(group);
0422         QCOMPARE((int)mainToolBar->toolButtonStyle(), (int)toolButtonStyle);
0423         QCOMPARE((int)otherToolBar->toolButtonStyle(), (int)toolButtonStyle);
0424 
0425 #ifndef Q_OS_WIN // the change notification uses DBus
0426         // Now change KDE-global setting
0427         changeGlobalToolButtonStyleSetting(QStringLiteral("IconOnly"), QStringLiteral("TextOnly"));
0428 
0429         if (selectedDefaultForMainToolbar) {
0430             QCOMPARE((int)mainToolBar->toolButtonStyle(), (int)Qt::ToolButtonIconOnly);
0431         } else {
0432             QCOMPARE((int)mainToolBar->toolButtonStyle(), (int)toolButtonStyle);
0433         }
0434 
0435         if (selectedDefaultForOtherToolbar) {
0436             QCOMPARE((int)otherToolBar->toolButtonStyle(), (int)Qt::ToolButtonTextOnly);
0437         } else {
0438             QCOMPARE((int)otherToolBar->toolButtonStyle(), (int)toolButtonStyle);
0439         }
0440 #endif
0441     }
0442 }
0443 
0444 void tst_KToolBar::testToolButtonStyleXmlGui_data()
0445 {
0446     QTest::addColumn<Qt::ToolButtonStyle>("toolButtonStyle");
0447     // Expected style after KDE-global is changed to main=IconOnly/other=TextOnly
0448     QTest::addColumn<Qt::ToolButtonStyle>("expectedStyleMainToolbar");
0449     QTest::addColumn<Qt::ToolButtonStyle>("expectedStyleOtherToolbar"); // xml says text-under-icons, user-selected should always win
0450     QTest::addColumn<Qt::ToolButtonStyle>("expectedStyleCleanToolbar"); // should always follow kde-global -> always textonly.
0451 
0452     QTest::newRow("Qt::ToolButtonTextUnderIcon") << Qt::ToolButtonTextUnderIcon << Qt::ToolButtonTextUnderIcon << Qt::ToolButtonTextUnderIcon
0453                                                  << Qt::ToolButtonTextOnly;
0454     QTest::newRow("Qt::ToolButtonTextBesideIcon") << Qt::ToolButtonTextBesideIcon
0455                                                   << Qt::ToolButtonIconOnly /* was default -> using kde global */ << Qt::ToolButtonTextBesideIcon
0456                                                   << Qt::ToolButtonTextOnly;
0457     QTest::newRow("Qt::ToolButtonIconOnly") << Qt::ToolButtonIconOnly << Qt::ToolButtonIconOnly << Qt::ToolButtonIconOnly << Qt::ToolButtonTextOnly;
0458     QTest::newRow("Qt::ToolButtonTextOnly") << Qt::ToolButtonTextOnly << Qt::ToolButtonTextOnly << Qt::ToolButtonTextOnly << Qt::ToolButtonTextOnly;
0459 }
0460 
0461 void tst_KToolBar::testToolButtonStyleXmlGui()
0462 {
0463     QFETCH(Qt::ToolButtonStyle, toolButtonStyle);
0464     QFETCH(Qt::ToolButtonStyle, expectedStyleMainToolbar);
0465     QFETCH(Qt::ToolButtonStyle, expectedStyleOtherToolbar);
0466     QFETCH(Qt::ToolButtonStyle, expectedStyleCleanToolbar);
0467     const Qt::ToolButtonStyle mainToolBarDefaultStyle = Qt::ToolButtonTextBesideIcon; // was TextUnderIcon before KDE-4.4.0
0468     KConfig config(QStringLiteral("tst_KToolBar"));
0469     KConfigGroup group(&config, "group");
0470     {
0471         TestXmlGuiWindow kmw(m_xml, "tst_ktoolbar.rc");
0472         kmw.createActions(QStringList() << QStringLiteral("go_up"));
0473         kmw.createGUI();
0474         KToolBar *mainToolBar = kmw.toolBarByName(QStringLiteral("mainToolBar"));
0475         KToolBar *otherToolBar = kmw.toolBarByName(QStringLiteral("otherToolBar"));
0476         KToolBar *cleanToolBar = kmw.toolBarByName(QStringLiteral("cleanToolBar"));
0477 
0478         QCOMPARE((int)mainToolBar->toolButtonStyle(), (int)mainToolBarDefaultStyle);
0479         QCOMPARE((int)otherToolBar->toolButtonStyle(), (int)Qt::ToolButtonTextUnderIcon); // from xml
0480         QCOMPARE((int)cleanToolBar->toolButtonStyle(), (int)Qt::ToolButtonTextBesideIcon);
0481 
0482         // Changing settings for a given toolbar, as user
0483         mainToolBar->setToolButtonStyle(toolButtonStyle);
0484         otherToolBar->setToolButtonStyle(toolButtonStyle);
0485 
0486         // Save settings
0487         kmw.saveMainWindowSettings(group);
0488 
0489 #ifndef Q_OS_WIN // the change notification uses DBus
0490         // Now change KDE-global setting
0491         changeGlobalToolButtonStyleSetting(QStringLiteral("IconOnly"), QStringLiteral("TextOnly"));
0492 
0493         QCOMPARE((int)mainToolBar->toolButtonStyle(), (int)expectedStyleMainToolbar);
0494         QCOMPARE((int)otherToolBar->toolButtonStyle(), (int)expectedStyleOtherToolbar);
0495         QCOMPARE((int)cleanToolBar->toolButtonStyle(), (int)expectedStyleCleanToolbar);
0496 #endif
0497     }
0498 }
0499 
0500 void tst_KToolBar::changeGlobalToolButtonStyleSetting(const QString &mainToolBar, const QString &otherToolBars)
0501 {
0502     KConfigGroup group(KSharedConfig::openConfig(), "Toolbar style");
0503     group.writeEntry("ToolButtonStyle", mainToolBar);
0504     group.writeEntry("ToolButtonStyleOtherToolbars", otherToolBars);
0505     group.sync();
0506 
0507     // Same dbus connect as the one in KToolBar. We want our spy to be notified of receiving it.
0508 #ifdef QT_DBUS_LIB
0509     QDBusConnection::sessionBus().connect(QString(),
0510                                           QStringLiteral("/KToolBar"),
0511                                           QStringLiteral("org.kde.KToolBar"),
0512                                           QStringLiteral("styleChanged"),
0513                                           this,
0514                                           SIGNAL(signalAppearanceChanged()));
0515     QSignalSpy spy(this, &tst_KToolBar::signalAppearanceChanged);
0516 
0517     KToolBar::emitToolbarStyleChanged();
0518     spy.wait(2000);
0519 #endif
0520 }
0521 
0522 void tst_KToolBar::deleteGlobalToolButtonStyleSetting()
0523 {
0524     KConfigGroup group(KSharedConfig::openConfig(), "Toolbar style");
0525     group.deleteEntry("ToolButtonStyle");
0526     group.deleteEntry("ToolButtonStyleOtherToolbars");
0527     KSharedConfig::openConfig()->sync();
0528 }
0529 
0530 void tst_KToolBar::testToolBarPosition()
0531 {
0532     TestXmlGuiWindow kmw(m_xml, "tst_ktoolbar.rc");
0533     kmw.createActions(QStringList() << QStringLiteral("go_up"));
0534     kmw.createGUI();
0535     KToolBar *mainToolBar = kmw.toolBarByName(QStringLiteral("mainToolBar"));
0536     KToolBar *otherToolBar = kmw.toolBarByName(QStringLiteral("otherToolBar"));
0537     QCOMPARE(kmw.toolBarArea(mainToolBar), Qt::TopToolBarArea);
0538     QCOMPARE(kmw.toolBarArea(otherToolBar), Qt::BottomToolBarArea);
0539 }
0540 
0541 void tst_KToolBar::testXmlGuiSwitching()
0542 {
0543     const QByteArray windowXml =
0544         "<?xml version = '1.0'?>\n"
0545         "<!DOCTYPE gui SYSTEM \"kpartgui.dtd\">\n"
0546         "<gui version=\"1\" name=\"foo\" >\n"
0547         "<MenuBar>\n"
0548         "</MenuBar>\n"
0549         "</gui>\n";
0550     TestXmlGuiWindow kmw(windowXml, "tst_ktoolbar.rc");
0551     kmw.createActions(QStringList() << QStringLiteral("go_up"));
0552     kmw.createGUI();
0553     TestGuiClient firstClient(m_xml);
0554     kmw.guiFactory()->addClient(&firstClient);
0555 
0556     {
0557         // qDebug() << "Added gui client";
0558         KToolBar *mainToolBar = firstClient.toolBarByName(QStringLiteral("mainToolBar"));
0559         KToolBar *otherToolBar = firstClient.toolBarByName(QStringLiteral("otherToolBar"));
0560         KToolBar *bigToolBar = firstClient.toolBarByName(QStringLiteral("bigToolBar"));
0561         KToolBar *hiddenToolBar = firstClient.toolBarByName(QStringLiteral("hiddenToolBar"));
0562         KToolBar *secondHiddenToolBar = firstClient.toolBarByName(QStringLiteral("secondHiddenToolBar"));
0563         QCOMPARE(hiddenToolBar->isHidden(), true);
0564         QCOMPARE(secondHiddenToolBar->isHidden(), true);
0565         // Make (unsaved) changes as user
0566         QMetaObject::invokeMethod(mainToolBar, "slotContextTextRight"); // mainToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
0567         QMetaObject::invokeMethod(mainToolBar, "slotContextRight"); // kmw.addToolBar(Qt::RightToolBarArea, mainToolBar);
0568         otherToolBar->setIconDimensions(35);
0569         bigToolBar->setIconDimensions(35);
0570         bigToolBar->hide();
0571         hiddenToolBar->show();
0572     }
0573     kmw.guiFactory()->removeClient(&firstClient);
0574     // qDebug() << "Removed gui client";
0575     QVERIFY(!kmw.guiFactory()->container(QStringLiteral("mainToolBar"), &kmw));
0576     QVERIFY(!kmw.guiFactory()->container(QStringLiteral("otherToolBar"), &kmw));
0577     QVERIFY(!kmw.guiFactory()->container(QStringLiteral("bigToolBar"), &kmw));
0578     QVERIFY(!kmw.guiFactory()->container(QStringLiteral("mainToolBar"), &firstClient));
0579     QVERIFY(!kmw.guiFactory()->container(QStringLiteral("otherToolBar"), &firstClient));
0580     QVERIFY(!kmw.guiFactory()->container(QStringLiteral("bigToolBar"), &firstClient));
0581 
0582     kmw.guiFactory()->addClient(&firstClient);
0583     // qDebug() << "Re-added gui client";
0584     KToolBar *mainToolBar = firstClient.toolBarByName(QStringLiteral("mainToolBar"));
0585     KToolBar *otherToolBar = firstClient.toolBarByName(QStringLiteral("otherToolBar"));
0586     KToolBar *bigToolBar = firstClient.toolBarByName(QStringLiteral("bigToolBar"));
0587     KToolBar *cleanToolBar = firstClient.toolBarByName(QStringLiteral("cleanToolBar"));
0588     KToolBar *hiddenToolBar = firstClient.toolBarByName(QStringLiteral("hiddenToolBar"));
0589     KToolBar *secondHiddenToolBar = firstClient.toolBarByName(QStringLiteral("secondHiddenToolBar"));
0590     QCOMPARE((int)mainToolBar->toolButtonStyle(), (int)Qt::ToolButtonTextBesideIcon);
0591     QCOMPARE(mainToolBar->isHidden(), false);
0592     QCOMPARE(kmw.toolBarArea(mainToolBar), Qt::RightToolBarArea);
0593     QCOMPARE(mainToolBar->iconSize().width(), KIconLoader::global()->currentSize(KIconLoader::MainToolbar));
0594     QCOMPARE(otherToolBar->iconSize().width(), 35);
0595     QCOMPARE(bigToolBar->iconSize().width(), 35);
0596     QCOMPARE(cleanToolBar->iconSize().width(), KIconLoader::global()->currentSize(KIconLoader::Toolbar));
0597     QCOMPARE(bigToolBar->isHidden(), true);
0598     QCOMPARE(hiddenToolBar->isHidden(), false);
0599     QCOMPARE(secondHiddenToolBar->isHidden(), true);
0600 
0601     // Now change KDE-global setting, what happens to unsaved changes?
0602     changeGlobalIconSizeSetting(32, 33);
0603     QCOMPARE(bigToolBar->iconSize().width(), 35); // fine now, saved or unsaved makes no difference
0604     QCOMPARE(otherToolBar->iconSize().width(), 35);
0605 
0606     // Now save, and check what we saved
0607     KConfig config(QStringLiteral("tst_KToolBar"));
0608     KConfigGroup group(&config, "group");
0609     kmw.saveMainWindowSettings(group);
0610     QCOMPARE(group.group("Toolbar bigToolBar").readEntry("IconSize", 0), 35);
0611     QCOMPARE(group.group("Toolbar otherToolBar").readEntry("IconSize", 0), 35);
0612     QVERIFY(!group.group("Toolbar cleanToolBar").hasKey("IconSize"));
0613     // QCOMPARE(group.group("Toolbar bigToolBar").readEntry("Hidden", false), true);
0614     // QVERIFY(!group.group("Toolbar cleanToolBar").hasKey("Hidden"));
0615     // QVERIFY(!group.group("Toolbar hiddenToolBar").hasKey("Hidden"));
0616 
0617     // Recreate window and apply config; is hidden toolbar shown as expected?
0618     {
0619         TestXmlGuiWindow kmw2(windowXml, "tst_ktoolbar.rc");
0620         kmw2.createActions(QStringList() << QStringLiteral("go_up"));
0621         kmw2.createGUI();
0622         TestGuiClient firstClient(m_xml);
0623         kmw2.guiFactory()->addClient(&firstClient);
0624 
0625         KToolBar *mainToolBar = firstClient.toolBarByName(QStringLiteral("mainToolBar"));
0626         KToolBar *otherToolBar = firstClient.toolBarByName(QStringLiteral("otherToolBar"));
0627         KToolBar *bigToolBar = firstClient.toolBarByName(QStringLiteral("bigToolBar"));
0628         KToolBar *hiddenToolBar = firstClient.toolBarByName(QStringLiteral("hiddenToolBar"));
0629         KToolBar *secondHiddenToolBar = firstClient.toolBarByName(QStringLiteral("secondHiddenToolBar"));
0630         QCOMPARE(bigToolBar->isHidden(), false);
0631         QCOMPARE(hiddenToolBar->isHidden(), true);
0632         QCOMPARE(secondHiddenToolBar->isHidden(), true);
0633 
0634         kmw2.show();
0635 
0636         // Check that secondHiddenToolBar is not shown+hidden immediately?
0637         m_showWasCalled = false;
0638         secondHiddenToolBar->installEventFilter(this);
0639         kmw2.applyMainWindowSettings(group);
0640 
0641         QCOMPARE(mainToolBar->isHidden(), false);
0642         QCOMPARE(kmw2.toolBarArea(mainToolBar), Qt::RightToolBarArea);
0643         QCOMPARE(otherToolBar->iconSize().width(), 35);
0644         QCOMPARE(bigToolBar->iconSize().width(), 35);
0645         QCOMPARE(bigToolBar->isHidden(), true);
0646         QCOMPARE(hiddenToolBar->isHidden(), false);
0647         QCOMPARE(secondHiddenToolBar->isHidden(), true);
0648         QVERIFY(!m_showWasCalled);
0649     }
0650 }
0651 
0652 void tst_KToolBar::testKAuthorizedDisableToggleAction()
0653 {
0654     TestXmlGuiWindow kmw(m_xml, "tst_ktoolbar.rc");
0655     kmw.createGUI();
0656 
0657     const auto toolbars = kmw.toolBars();
0658     for (KToolBar *toolbar : toolbars) {
0659         QVERIFY(!toolbar->toggleViewAction()->isEnabled());
0660     }
0661 }
0662 
0663 bool tst_KToolBar::eventFilter(QObject *watched, QEvent *event)
0664 {
0665     Q_UNUSED(watched);
0666     if (event->type() == QEvent::Show) {
0667         m_showWasCalled = true;
0668         return true;
0669     }
0670     return false;
0671 }
0672 
0673 #include "ktoolbar_unittest.moc"