diff --git a/kcms/componentchooser/CMakeLists.txt b/kcms/componentchooser/CMakeLists.txt index db40bec24..822df8794 100644 --- a/kcms/componentchooser/CMakeLists.txt +++ b/kcms/componentchooser/CMakeLists.txt @@ -1,43 +1,49 @@ # KI18N Translation Domain for this library add_definitions(-DTRANSLATION_DOMAIN=\"kcm5_componentchooser\") add_subdirectory( componentservices ) ########### next target ############### set(kcm_componentchooser_SRCS componentchooser.cpp componentchooserbrowser.cpp componentchooserfilemanager.cpp componentchooseremail.cpp componentchooserterminal.cpp kcm_componentchooser.cpp ) ki18n_wrap_ui(kcm_componentchooser_SRCS browserconfig_ui.ui filemanagerconfig_ui.ui emailclientconfig_ui.ui componentchooser_ui.ui componentconfig_ui.ui terminalemulatorconfig_ui.ui ) add_library(kcm_componentchooser MODULE ${kcm_componentchooser_SRCS}) target_link_libraries(kcm_componentchooser + KF5::I18n + KF5::Completion + KF5::ConfigWidgets + KF5::Service + KF5::KIOWidgets KF5::KDELibs4Support + Qt5::DBus Qt5::X11Extras ) install(TARGETS kcm_componentchooser DESTINATION ${KDE_INSTALL_PLUGINDIR} ) ########### install files ############### install( FILES componentchooser.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) diff --git a/kcms/componentchooser/browserconfig_ui.ui b/kcms/componentchooser/browserconfig_ui.ui index e5361251b..aa5f649ad 100644 --- a/kcms/componentchooser/browserconfig_ui.ui +++ b/kcms/componentchooser/browserconfig_ui.ui @@ -1,197 +1,197 @@ BrowserConfig_UI 0 0 432 218 0 0 0 0 <qt>Open <b>http</b> and <b>https</b> URLs</qt> in an application based on the contents of the URL true in the following application: Qt::Horizontal QSizePolicy::Fixed 20 0 false with the following command: Qt::Horizontal QSizePolicy::Fixed 20 0 false false ... Qt::Vertical QSizePolicy::Expanding 0 20 KLineEdit QLineEdit -
KDE/KLineEdit
+
KLineEdit
radioService toggled(bool) browserCombo setEnabled(bool) 20 20 20 20 radioExec toggled(bool) lineExec setEnabled(bool) 20 20 20 20 radioExec toggled(bool) btnSelectApplication setEnabled(bool) 20 20 20 20
diff --git a/kcms/componentchooser/componentchooserterminal.cpp b/kcms/componentchooser/componentchooserterminal.cpp index aa715086b..e12db1e08 100644 --- a/kcms/componentchooser/componentchooserterminal.cpp +++ b/kcms/componentchooser/componentchooserterminal.cpp @@ -1,114 +1,113 @@ /*************************************************************************** componentchooser.cpp - description ------------------- copyright : (C) 2002 by Joseph Wenninger email : jowenn@kde.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License verstion 2 as * * published by the Free Software Foundation * * * ***************************************************************************/ #include "componentchooserterminal.h" #include #include #include #include -#include #include #include #include #include #include #include #include #include #include #include "../migrationlib/kdelibs4config.h" CfgTerminalEmulator::CfgTerminalEmulator(QWidget *parent) : QWidget(parent), Ui::TerminalEmulatorConfig_UI(), CfgPlugin() { setupUi(this); connect(terminalLE, &QLineEdit::textChanged, this, &CfgTerminalEmulator::configChanged); connect(terminalCB, &QRadioButton::toggled, this, &CfgTerminalEmulator::configChanged); connect(otherCB, &QRadioButton::toggled, this, &CfgTerminalEmulator::configChanged); connect(btnSelectTerminal, &QToolButton::clicked, this, &CfgTerminalEmulator::selectTerminalApp); } CfgTerminalEmulator::~CfgTerminalEmulator() { } void CfgTerminalEmulator::configChanged() { emit changed(true); } void CfgTerminalEmulator::defaults() { load(nullptr); } void CfgTerminalEmulator::load(KConfig *) { KConfigGroup config(KSharedConfig::openConfig(QStringLiteral("kdeglobals")), "General"); QString terminal = config.readPathEntry("TerminalApplication",QStringLiteral("konsole")); if (terminal == QLatin1String("konsole")) { terminalLE->setText(QStringLiteral("xterm")); terminalCB->setChecked(true); } else { terminalLE->setText(terminal); otherCB->setChecked(true); } emit changed(false); } void CfgTerminalEmulator::save(KConfig *) { KSharedConfig::Ptr profile = KSharedConfig::openConfig(QStringLiteral("kdeglobals")); KConfigGroup config(profile, QStringLiteral("General")); const QString terminal = terminalCB->isChecked() ? QStringLiteral("konsole") : terminalLE->text(); config.writePathEntry("TerminalApplication", terminal); // KConfig::Normal|KConfig::Global); config.sync(); Kdelibs4SharedConfig::syncConfigGroup(QLatin1String("General"), "kdeglobals"); KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged); QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.klauncher5"), QStringLiteral("/KLauncher"), QStringLiteral("org.kde.KLauncher"), QStringLiteral("reparseConfiguration")); QDBusConnection::sessionBus().send(message); emit changed(false); } void CfgTerminalEmulator::selectTerminalApp() { QList urlList; KOpenWithDialog dlg(urlList, i18n("Select preferred terminal application:"), QString(), this); // hide "Run in &terminal" here, we don't need it for a Terminal Application dlg.hideRunInTerminal(); if (dlg.exec() != QDialog::Accepted) return; QString client = dlg.text(); if (!client.isEmpty()) { terminalLE->setText(client); } } // vim: sw=4 ts=4 noet diff --git a/kcms/componentchooser/componentconfig_ui.ui b/kcms/componentchooser/componentconfig_ui.ui index a6604a61e..03308965d 100644 --- a/kcms/componentchooser/componentconfig_ui.ui +++ b/kcms/componentchooser/componentconfig_ui.ui @@ -1,49 +1,49 @@ ComponentConfig_UI 0 Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop true Qt::Vertical QSizePolicy::Expanding 0 20 KComboBox QComboBox -
KDE/KComboBox
+
KComboBox
diff --git a/kcms/componentchooser/emailclientconfig_ui.ui b/kcms/componentchooser/emailclientconfig_ui.ui index 6746562c4..f5fd8e6a9 100644 --- a/kcms/componentchooser/emailclientconfig_ui.ui +++ b/kcms/componentchooser/emailclientconfig_ui.ui @@ -1,184 +1,184 @@ EmailClientConfig_UI 0 Kmail is the standard Mail program for the Plasma desktop. &Use KMail as preferred email client Select this option if you want to use any other mail program. Use a different &email client: Qt::Horizontal QSizePolicy::Fixed 20 0 false Optional placeholders: <ul> <li>%t: Recipient's address</li> <li>%s: Subject</li> <li>%c: Carbon Copy (CC)</li> <li>%b: Blind Carbon Copy (BCC)</li> <li>%B: Template body text</li> <li>%A: Attachment </li> <li>%u: Full mailto: URL </li></ul> Press this button to select your favorite email client. Please note that the file you select has to have the executable attribute set in order to be accepted.<br/> You can also use several placeholders which will be replaced with the actual values when the email client is called:<ul> <li>%t: Recipient's address</li> <li>%s: Subject</li> <li>%c: Carbon Copy (CC)</li> <li>%b: Blind Carbon Copy (BCC)</li> <li>%B: Template body text</li> <li>%A: Attachment </li> </ul> false Click here to browse for the mail program file. ... Qt::Horizontal QSizePolicy::Fixed 20 0 false Activate this option if you want the selected email client to be executed in a terminal (e.g. <em>Konsole</em>). &Run in terminal Qt::Vertical QSizePolicy::Expanding 0 20 KLineEdit QLineEdit -
KDE/KLineEdit
+
KLineEdit
otherCB toggled(bool) chkRunTerminal setEnabled(bool) 20 20 20 20 otherCB toggled(bool) txtEMailClient setEnabled(bool) 20 20 20 20 otherCB toggled(bool) btnSelectEmail setEnabled(bool) 20 20 20 20
diff --git a/kcms/cursortheme/CMakeLists.txt b/kcms/cursortheme/CMakeLists.txt index 35981044b..bf2106b35 100644 --- a/kcms/cursortheme/CMakeLists.txt +++ b/kcms/cursortheme/CMakeLists.txt @@ -1,60 +1,62 @@ # KI18N Translation Domain for this library add_definitions(-DTRANSLATION_DOMAIN=\"kcm_cursortheme\") include_directories( ${LIBUSB_INCLUDE_DIR} ) set( libnoinst_SRCS xcursor/thememodel.cpp xcursor/cursortheme.cpp xcursor/xcursortheme.cpp xcursor/previewwidget.cpp xcursor/sortproxymodel.cpp ../krdb/krdb.cpp ) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/xcursor/ ) set(klauncher_xml ${KINIT_DBUS_INTERFACES_DIR}/kf5_org.kde.KLauncher.xml) qt5_add_dbus_interface(libnoinst_SRCS ${klauncher_xml} klauncher_iface) ########### next target ############### set(kcm_cursortheme_PART_SRCS kcmcursortheme.cpp ${libnoinst_SRCS}) add_library(kcm_cursortheme MODULE ${kcm_cursortheme_PART_SRCS}) target_link_libraries(kcm_cursortheme Qt5::DBus Qt5::X11Extras Qt5::Quick KF5::Archive KF5::KCMUtils KF5::I18n + KF5::GuiAddons + KF5::WindowSystem KF5::KIOCore KF5::KIOWidgets KF5::KDELibs4Support KF5::NewStuff KF5::QuickAddons ${X11_LIBRARIES} XCB::XCB ) if (X11_Xcursor_FOUND) target_link_libraries(kcm_cursortheme ${X11_Xcursor_LIB}) endif () if (X11_Xfixes_FOUND) target_link_libraries(kcm_cursortheme ${X11_Xfixes_LIB}) endif () install(TARGETS kcm_cursortheme DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms ) kcoreaddons_desktop_to_json(kcm_cursortheme "kcm_cursortheme.desktop") ########### install files ############### install( FILES kcm_cursortheme.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) install( FILES xcursor/xcursor.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR} ) kpackage_install_package(package kcm_cursortheme kcms) diff --git a/kcms/cursortheme/kcmcursortheme.cpp b/kcms/cursortheme/kcmcursortheme.cpp index abf35288c..016b0fc17 100644 --- a/kcms/cursortheme/kcmcursortheme.cpp +++ b/kcms/cursortheme/kcmcursortheme.cpp @@ -1,648 +1,647 @@ /* * Copyright © 2003-2007 Fredrik Höglund * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "kcmcursortheme.h" #include "xcursor/thememodel.h" #include "xcursor/sortproxymodel.h" #include "xcursor/cursortheme.h" #include "xcursor/previewwidget.h" #include "../krdb/krdb.h" #include #include #include #include #include #include #include #include #include #include #include -#include #include #include #include #include #include #include #include #include #ifdef HAVE_XFIXES # include #endif K_PLUGIN_FACTORY_WITH_JSON(CursorThemeConfigFactory, "kcm_cursortheme.json", registerPlugin();) CursorThemeConfig::CursorThemeConfig(QObject *parent, const QVariantList &args) : KQuickAddons::ConfigModule(parent, args), m_appliedSize(0), m_preferredSize(0), m_selectedThemeRow(-1), m_selectedSizeRow(-1), m_originalSelectedThemeRow(-1), m_canInstall(true), m_canResize(true), m_canConfigure(true) { qmlRegisterType("org.kde.private.kcm_cursortheme", 1, 0, "PreviewWidget"); qmlRegisterType(); KAboutData* aboutData = new KAboutData(QStringLiteral("kcm_cursortheme"), i18n("Cursors"), QStringLiteral("1.0"), QString(), KAboutLicense::GPL, i18n("(c) 2003-2007 Fredrik Höglund")); aboutData->addAuthor(i18n("Fredrik Höglund")); aboutData->addAuthor(i18n("Marco Martin")); setAboutData(aboutData); m_model = new CursorThemeModel(this); m_proxyModel = new SortProxyModel(this); m_proxyModel->setSourceModel(m_model); m_proxyModel->setFilterCaseSensitivity(Qt::CaseSensitive); m_proxyModel->sort(NameColumn, Qt::AscendingOrder); m_sizesModel = new QStandardItemModel(this); // Disable the install button if we can't install new themes to ~/.icons, // or Xcursor isn't set up to look for cursor themes there. if (!m_model->searchPaths().contains(QDir::homePath() + "/.icons") || !iconsIsWritable()) { setCanInstall(false); } } CursorThemeConfig::~CursorThemeConfig() { /* */ } void CursorThemeConfig::setCanInstall(bool can) { if (m_canInstall == can) { return; } m_canInstall = can; emit canInstallChanged(); } bool CursorThemeConfig::canInstall() const { return m_canInstall; } void CursorThemeConfig::setCanResize(bool can) { if (m_canResize == can) { return; } m_canResize = can; emit canResizeChanged(); } bool CursorThemeConfig::canResize() const { return m_canResize; } void CursorThemeConfig::setCanConfigure(bool can) { if (m_canConfigure == can) { return; } m_canConfigure = can; emit canConfigureChanged(); } bool CursorThemeConfig::canConfigure() const { return m_canConfigure; } void CursorThemeConfig::setSelectedThemeRow(int row) { if (m_selectedThemeRow == row) { return; } m_selectedThemeRow = row; emit selectedThemeRowChanged(); updateSizeComboBox(); QModelIndex selected = selectedIndex(); if (selected.isValid()) { const CursorTheme *theme = m_proxyModel->theme(selected); } setNeedsSave(m_originalSelectedThemeRow != m_selectedThemeRow || m_originalPreferredSize != m_preferredSize); } int CursorThemeConfig::selectedThemeRow() const { return m_selectedThemeRow; } void CursorThemeConfig::setSelectedSizeRow(int row) { Q_ASSERT (row < m_sizesModel->rowCount() && row >= 0); // we don't return early if m_selectedSizeRow == row as this is called after the model is changed m_selectedSizeRow = row; emit selectedSizeRowChanged(); int size = m_sizesModel->item(row)->data().toInt(); m_preferredSize = size; setNeedsSave(m_originalSelectedThemeRow != m_selectedThemeRow || m_originalPreferredSize != m_preferredSize); } int CursorThemeConfig::selectedSizeRow() const { return m_selectedSizeRow; } bool CursorThemeConfig::downloadingFile() const { return m_tempCopyJob; } QAbstractItemModel *CursorThemeConfig::cursorsModel() { return m_proxyModel; } QAbstractItemModel *CursorThemeConfig::sizesModel() { return m_sizesModel; } bool CursorThemeConfig::iconsIsWritable() const { const QFileInfo icons = QFileInfo(QDir::homePath() + "/.icons"); const QFileInfo home = QFileInfo(QDir::homePath()); return ((icons.exists() && icons.isDir() && icons.isWritable()) || (!icons.exists() && home.isWritable())); } void CursorThemeConfig::updateSizeComboBox() { // clear the combo box m_sizesModel->clear(); // refill the combo box and adopt its icon size QModelIndex selected = selectedIndex(); int maxIconWidth = 0; int maxIconHeight = 0; if (selected.isValid()) { const CursorTheme *theme = m_proxyModel->theme(selected); const QList sizes = theme->availableSizes(); QIcon m_icon; // only refill the combobox if there is more that 1 size if (sizes.size() > 1) { int i; QList comboBoxList; QPixmap m_pixmap; // insert the items m_pixmap = theme->createIcon(0); if (m_pixmap.width() > maxIconWidth) { maxIconWidth = m_pixmap.width(); } if (m_pixmap.height() > maxIconHeight) { maxIconHeight = m_pixmap.height(); } QStandardItem *item = new QStandardItem(QIcon(m_pixmap), i18nc("@item:inlistbox size", "Resolution dependent")); item->setData(0); m_sizesModel->appendRow(item); comboBoxList << 0; foreach (i, sizes) { m_pixmap = theme->createIcon(i); if (m_pixmap.width() > maxIconWidth) { maxIconWidth = m_pixmap.width(); } if (m_pixmap.height() > maxIconHeight) { maxIconHeight = m_pixmap.height(); } QStandardItem *item = new QStandardItem(QIcon(m_pixmap), QString::number(i)); item->setData(i); m_sizesModel->appendRow(item); comboBoxList << i; }; // select an item int selectItem = comboBoxList.indexOf(m_preferredSize); // m_preferredSize not available for this theme if (selectItem < 0) { /* Search the value next to m_preferredSize. The first entry (0) is ignored. (If m_preferredSize would have been 0, then we would had found it yet. As m_preferredSize is not 0, we won't default to "automatic size".)*/ int j; int distance; int smallestDistance; selectItem = 1; j = comboBoxList.value(selectItem); smallestDistance = j < m_preferredSize ? m_preferredSize - j : j - m_preferredSize; for (int i = 2; i < comboBoxList.size(); ++i) { j = comboBoxList.value(i); distance = j < m_preferredSize ? m_preferredSize - j : j - m_preferredSize; if (distance < smallestDistance || (distance == smallestDistance && j > m_preferredSize)) { smallestDistance = distance; selectItem = i; }; } }; if (selectItem < 0) { selectItem = 0; } setSelectedSizeRow(selectItem); }; }; // enable or disable the combobox KConfig c("kcminputrc"); KConfigGroup cg(&c, "Mouse"); if (cg.isEntryImmutable("cursorSize")) { setCanResize(false); } else { setCanResize(m_sizesModel->rowCount() > 0); }; } bool CursorThemeConfig::applyTheme(const CursorTheme *theme, const int size) { // Require the Xcursor version that shipped with X11R6.9 or greater, since // in previous versions the Xfixes code wasn't enabled due to a bug in the // build system (freedesktop bug #975). #if HAVE_XFIXES && XFIXES_MAJOR >= 2 && XCURSOR_LIB_VERSION >= 10105 if (!theme) { return false; } if (!CursorTheme::haveXfixes()) { return false; } QByteArray themeName = QFile::encodeName(theme->name()); // Set up the proper launch environment for newly started apps OrgKdeKLauncherInterface klauncher(QStringLiteral("org.kde.klauncher5"), QStringLiteral("/KLauncher"), QDBusConnection::sessionBus()); klauncher.setLaunchEnv(QStringLiteral("XCURSOR_THEME"), themeName); // Update the Xcursor X resources runRdb(0); // Notify all applications that the cursor theme has changed KGlobalSettings::self()->emitChange(KGlobalSettings::CursorChanged); // Reload the standard cursors QStringList names; // Qt cursors names << "left_ptr" << "up_arrow" << "cross" << "wait" << "left_ptr_watch" << "ibeam" << "size_ver" << "size_hor" << "size_bdiag" << "size_fdiag" << "size_all" << "split_v" << "split_h" << "pointing_hand" << "openhand" << "closedhand" << "forbidden" << "whats_this" << "copy" << "move" << "link"; // X core cursors names << "X_cursor" << "right_ptr" << "hand1" << "hand2" << "watch" << "xterm" << "crosshair" << "left_ptr_watch" << "center_ptr" << "sb_h_double_arrow" << "sb_v_double_arrow" << "fleur" << "top_left_corner" << "top_side" << "top_right_corner" << "right_side" << "bottom_right_corner" << "bottom_side" << "bottom_left_corner" << "left_side" << "question_arrow" << "pirate"; foreach (const QString &name, names) { XFixesChangeCursorByName(QX11Info::display(), theme->loadCursor(name, size), QFile::encodeName(name)); } return true; #else Q_UNUSED(theme) return false; #endif } void CursorThemeConfig::save() { const CursorTheme *theme = selectedIndex().isValid() ? m_proxyModel->theme(selectedIndex()) : nullptr; KConfig config("kcminputrc"); KConfigGroup c(&config, "Mouse"); if (theme) { c.writeEntry("cursorTheme", theme->name()); }; c.writeEntry("cursorSize", m_preferredSize); c.sync(); if (!applyTheme(theme, m_preferredSize)) { emit showInfoMessage(i18n("You have to restart the Plasma session for these changes to take effect.")); } m_appliedIndex = selectedIndex(); m_appliedSize = m_preferredSize; m_originalSelectedThemeRow = m_selectedThemeRow; m_originalPreferredSize = m_preferredSize; setNeedsSave(false); } void CursorThemeConfig::load() { // Get the name of the theme libXcursor currently uses QString currentTheme; if (QX11Info::isPlatformX11()) { currentTheme = XcursorGetTheme(QX11Info::display()); } // Get the name of the theme KDE is configured to use KConfig c("kcminputrc"); KConfigGroup cg(&c, "Mouse"); currentTheme = cg.readEntry("cursorTheme", currentTheme); // Find the theme in the listview if (!currentTheme.isEmpty()) { m_appliedIndex = m_proxyModel->findIndex(currentTheme); } else { m_appliedIndex = m_proxyModel->defaultIndex(); } // Disable the listview and the buttons if we're in kiosk mode if (cg.isEntryImmutable("cursorTheme")) { setCanConfigure(false); setCanInstall(false); } const CursorTheme *theme = m_proxyModel->theme(m_appliedIndex); setSelectedThemeRow(m_appliedIndex.row()); m_originalSelectedThemeRow = m_selectedThemeRow; // Load cursor size int size = cg.readEntry("cursorSize", 0); if (size <= 0) { m_preferredSize = 0; } else { m_preferredSize = size; } m_originalPreferredSize = m_preferredSize; updateSizeComboBox(); // This handles also the kiosk mode m_appliedSize = size; setNeedsSave(false); } void CursorThemeConfig::defaults() { QModelIndex defaultIndex = m_proxyModel->findIndex("breeze_cursors"); setSelectedThemeRow(defaultIndex.row()); m_preferredSize = 0; updateSizeComboBox(); setNeedsSave(m_originalSelectedThemeRow != m_selectedThemeRow || m_originalPreferredSize != m_preferredSize); } void CursorThemeConfig::selectionChanged() { updateSizeComboBox(); setNeedsSave(m_originalSelectedThemeRow != m_selectedThemeRow || m_originalPreferredSize != m_preferredSize); //setNeedsSave(m_appliedIndex != selectedIndex()); } QModelIndex CursorThemeConfig::selectedIndex() const { return m_proxyModel->index(m_selectedThemeRow, 0); } void CursorThemeConfig::getNewClicked() { KNS3::DownloadDialog dialog("xcursor.knsrc", nullptr); if (dialog.exec()) { KNS3::Entry::List list = dialog.changedEntries(); if (!list.isEmpty()) { for (const KNS3::Entry& entry : list) { if (entry.status() == KNS3::Entry::Deleted) { for (const QString& deleted : entry.uninstalledFiles()) { QVector list = deleted.splitRef(QLatin1Char('/')); if (list.last() == QLatin1Char('*')) { list.takeLast(); } QModelIndex idx = m_model->findIndex(list.last().toString()); if (idx.isValid()) { m_model->removeTheme(idx); } } } else if (entry.status() == KNS3::Entry::Installed) { for (const QString& created : entry.installedFiles()) { QStringList list = created.split(QLatin1Char('/')); if (list.last() == QLatin1Char('*')) { list.takeLast(); } // Because we sometimes get some extra slashes in the installed files list list.removeAll({}); // Because we'll also get the containing folder, if it was not already there // we need to ignore it. if (list.last() == QLatin1String(".icons")) { continue; } m_model->addTheme(list.join(QLatin1Char('/'))); } } } } } } void CursorThemeConfig::installThemeFromFile(const QUrl &url) { if (url.isLocalFile()) { installThemeFile(url.toLocalFile()); return; } if (m_tempCopyJob) { return; } m_tempInstallFile.reset(new QTemporaryFile()); if (!m_tempInstallFile->open()) { emit showErrorMessage(i18n("Unable to create a temporary file.")); m_tempInstallFile.reset(); return; } m_tempCopyJob = KIO::file_copy(url,QUrl::fromLocalFile(m_tempInstallFile->fileName()), -1, KIO::Overwrite); m_tempCopyJob->uiDelegate()->setAutoErrorHandlingEnabled(true); emit downloadingFileChanged(); connect(m_tempCopyJob, &KIO::FileCopyJob::result, this, [this, url](KJob *job) { if (job->error() != KJob::NoError) { emit showErrorMessage(i18n("Unable to download the icon theme archive: %1", job->errorText())); return; } installThemeFile(m_tempInstallFile->fileName()); m_tempInstallFile.reset(); }); connect(m_tempCopyJob, &QObject::destroyed, this, &CursorThemeConfig::downloadingFileChanged); } void CursorThemeConfig::installThemeFile(const QString &path) { KTar archive(path); archive.open(QIODevice::ReadOnly); const KArchiveDirectory *archiveDir = archive.directory(); QStringList themeDirs; // Extract the dir names of the cursor themes in the archive, and // append them to themeDirs foreach(const QString &name, archiveDir->entries()) { const KArchiveEntry *entry = archiveDir->entry(name); if (entry->isDirectory() && entry->name().toLower() != "default") { const KArchiveDirectory *dir = static_cast(entry); if (dir->entry("index.theme") && dir->entry("cursors")) { themeDirs << dir->name(); } } } if (themeDirs.isEmpty()) { emit showErrorMessage(i18n("The file is not a valid icon theme archive.")); return; } // The directory we'll install the themes to QString destDir = QDir::homePath() + "/.icons/"; if (!QDir().mkpath(destDir)) { emit showErrorMessage(i18n("Failed to create 'icons' folder.")); return; }; // Process each cursor theme in the archive foreach (const QString &dirName, themeDirs) { QDir dest(destDir + dirName); if (dest.exists()) { QString question = i18n("A theme named %1 already exists in your icon " "theme folder. Do you want replace it with this one?", dirName); int answer = KMessageBox::warningContinueCancel(nullptr, question, i18n("Overwrite Theme?"), KStandardGuiItem::overwrite()); if (answer != KMessageBox::Continue) { continue; } // ### If the theme that's being replaced is the current theme, it // will cause cursor inconsistencies in newly started apps. } // ### Should we check if a theme with the same name exists in a global theme dir? // If that's the case it will effectively replace it, even though the global theme // won't be deleted. Checking for this situation is easy, since the global theme // will be in the listview. Maybe this should never be allowed since it might // result in strange side effects (from the average users point of view). OTOH // a user might want to do this 'upgrade' a global theme. const KArchiveDirectory *dir = static_cast (archiveDir->entry(dirName)); dir->copyTo(dest.path()); m_model->addTheme(dest); } archive.close(); emit showSuccessMessage(i18n("Theme installed successfully.")); m_model->refreshList(); } void CursorThemeConfig::removeTheme(int row) { QModelIndex idx = m_proxyModel->index(row, 0); if (!idx.isValid()) { return; } const CursorTheme *theme = m_proxyModel->theme(idx); // Don't let the user delete the currently configured theme if (idx == m_appliedIndex) { KMessageBox::sorry(nullptr, i18n("You cannot delete the theme you are currently " "using.
You have to switch to another theme first.
")); return; } // Get confirmation from the user QString question = i18n("Are you sure you want to remove the " "%1 cursor theme?
" "This will delete all the files installed by this theme.
", theme->title()); int answer = KMessageBox::warningContinueCancel(nullptr, question, i18n("Confirmation"), KStandardGuiItem::del()); if (answer != KMessageBox::Continue) { return; } // Delete the theme from the harddrive KIO::del(QUrl::fromLocalFile(theme->path())); // async // Remove the theme from the model m_proxyModel->removeTheme(idx); // TODO: // Since it's possible to substitute cursors in a system theme by adding a local // theme with the same name, we shouldn't remove the theme from the list if it's // still available elsewhere. We could add a // bool CursorThemeModel::tryAddTheme(const QString &name), and call that, but // since KIO::del() is an asynchronos operation, the theme we're deleting will be // readded to the list again before KIO has removed it. } #include "kcmcursortheme.moc" diff --git a/kcms/emoticons/CMakeLists.txt b/kcms/emoticons/CMakeLists.txt index ebf8edce7..7cdc43f4c 100644 --- a/kcms/emoticons/CMakeLists.txt +++ b/kcms/emoticons/CMakeLists.txt @@ -1,17 +1,18 @@ # KI18N Translation Domain for this library add_definitions(-DTRANSLATION_DOMAIN=\"kcm5_emoticons\") set(kcmemoticons_SRCS emoticonslist.cpp) ki18n_wrap_ui(kcmemoticons_SRCS emoticonslist.ui) add_library(kcm_emoticons MODULE ${kcmemoticons_SRCS}) target_link_libraries(kcm_emoticons KF5::NewStuff + KF5::Completion KF5::KDELibs4Support KF5::Emoticons) install(TARGETS kcm_emoticons DESTINATION ${KDE_INSTALL_PLUGINDIR} ) ########### install files ############### install( FILES emoticons.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) install( FILES emoticons.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR} ) diff --git a/kcms/lookandfeel/CMakeLists.txt b/kcms/lookandfeel/CMakeLists.txt index f6e5a73ee..0b92538c0 100644 --- a/kcms/lookandfeel/CMakeLists.txt +++ b/kcms/lookandfeel/CMakeLists.txt @@ -1,107 +1,108 @@ # KI18N Translation Domain for this library add_definitions(-DTRANSLATION_DOMAIN=\"kcm_lookandfeel\") configure_file (config-kcm.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kcm.h ) set(kcm_lookandfeel_SRCS kcmmain.cpp kcm.cpp ../krdb/krdb.cpp ../cursortheme/xcursor/cursortheme.cpp ../cursortheme/xcursor/xcursortheme.cpp ) set(klauncher_xml ${KINIT_DBUS_INTERFACES_DIR}/kf5_org.kde.KLauncher.xml) qt5_add_dbus_interface(kcm_lookandfeel_SRCS ${klauncher_xml} klauncher_iface) add_library(kcm_lookandfeel MODULE ${kcm_lookandfeel_SRCS}) target_link_libraries(kcm_lookandfeel KF5::KIOWidgets KF5::CoreAddons + KF5::GuiAddons KF5::KCMUtils KF5::I18n KF5::Plasma KF5::PlasmaQuick KF5::KDELibs4Support KF5::Declarative KF5::QuickAddons KF5::NewStuff Qt5::DBus Qt5::Widgets Qt5::QuickWidgets ${X11_LIBRARIES} ) if(X11_FOUND) target_link_libraries(kcm_lookandfeel Qt5::X11Extras) endif() if (X11_Xcursor_FOUND) target_link_libraries(kcm_lookandfeel ${X11_Xcursor_LIB}) endif () if (X11_Xfixes_FOUND) target_link_libraries(kcm_lookandfeel ${X11_Xfixes_LIB}) endif () kcoreaddons_desktop_to_json(kcm_lookandfeel "kcm_lookandfeel.desktop" SERVICE_TYPES kcmodule.desktop) #this desktop file is installed only for retrocompatibility with sycoca install(FILES kcm_lookandfeel.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) install(TARGETS kcm_lookandfeel DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms) install(FILES lookandfeel.knsrc DESTINATION ${KDE_INSTALL_KNSRCDIR}) if(BUILD_TESTING) find_package(Qt5Test ${QT_MIN_VERSION} CONFIG REQUIRED) add_subdirectory(autotests) endif() kpackage_install_package(package kcm_lookandfeel kcms) ###### Command line tool set(lookandfeeltool_SRCS lnftool.cpp # TODO: load kcm plugin instead of using code copy kcm.cpp ../krdb/krdb.cpp ../cursortheme/xcursor/cursortheme.cpp ../cursortheme/xcursor/xcursortheme.cpp ) qt5_add_dbus_interface(lookandfeeltool_SRCS ${klauncher_xml} klauncher_iface) add_executable(lookandfeeltool ${lookandfeeltool_SRCS}) target_link_libraries(lookandfeeltool KF5::KIOWidgets KF5::CoreAddons KF5::KCMUtils KF5::I18n #TODO:kpackage KF5::Plasma KF5::PlasmaQuick KF5::KDELibs4Support KF5::Declarative KF5::QuickAddons KF5::NewStuff Qt5::DBus Qt5::Widgets Qt5::QuickWidgets ${X11_LIBRARIES} ) if(X11_FOUND) target_link_libraries(lookandfeeltool Qt5::X11Extras) endif() if (X11_Xcursor_FOUND) target_link_libraries(lookandfeeltool ${X11_Xcursor_LIB}) endif () if (X11_Xfixes_FOUND) target_link_libraries(lookandfeeltool ${X11_Xfixes_LIB}) endif () install( TARGETS lookandfeeltool ${KDE_INSTALL_TARGETS_DEFAULT_ARGS} ) diff --git a/kcms/style/kcmstyle.cpp b/kcms/style/kcmstyle.cpp index 0d814a867..81ca5e228 100644 --- a/kcms/style/kcmstyle.cpp +++ b/kcms/style/kcmstyle.cpp @@ -1,715 +1,714 @@ /* * KCMStyle * Copyright (C) 2002 Karol Szwed * Copyright (C) 2002 Daniel Molkentin * Copyright (C) 2007 Urs Wolfer * Copyright (C) 2009 by Davide Bettio * Portions Copyright (C) 2007 Paolo Capriotti * Portions Copyright (C) 2007 Ivan Cukic * Portions Copyright (C) 2008 by Petri Damsten * Portions Copyright (C) 2000 TrollTech AS. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2 as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "kcmstyle.h" #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) #include #endif #include "styleconfdialog.h" #include "ui_stylepreview.h" #include "ui_styleconfig.h" #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) #include #endif #include "../krdb/krdb.h" #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) #include #endif // X11 namespace cleanup #undef Bool #undef Below #undef KeyPress #undef KeyRelease /**** DLL Interface for kcontrol ****/ #include #include -#include K_PLUGIN_FACTORY(KCMStyleFactory, registerPlugin();) K_EXPORT_PLUGIN(KCMStyleFactory("kcmstyle")) extern "C" { Q_DECL_EXPORT void kcminit_style() { uint flags = KRdbExportQtSettings | KRdbExportGtkColors | KRdbExportQtColors | KRdbExportXftSettings | KRdbExportGtkTheme; KConfig _config( QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals ); KConfigGroup config(&_config, "X11"); // This key is written by the "colors" module. bool exportKDEColors = config.readEntry("exportKDEColors", true); if (exportKDEColors) flags |= KRdbExportColors; runRdb( flags ); } } class StylePreview : public QWidget, public Ui::StylePreview { public: StylePreview(QWidget *parent = nullptr) : QWidget(parent) { setupUi(this); // Ensure that the user can't toy with the child widgets. // Method borrowed from Qt's qtconfig. QList widgets = findChildren(); foreach (QWidget* widget, widgets) { widget->installEventFilter(this); widget->setFocusPolicy(Qt::NoFocus); } } bool eventFilter( QObject* /* obj */, QEvent* ev ) override { switch( ev->type() ) { case QEvent::MouseButtonPress: case QEvent::MouseButtonRelease: case QEvent::MouseButtonDblClick: case QEvent::MouseMove: case QEvent::KeyPress: case QEvent::KeyRelease: case QEvent::Enter: case QEvent::Leave: case QEvent::Wheel: case QEvent::ContextMenu: return true; // ignore default: break; } return false; } }; class StyleConfig : public QWidget, public Ui::StyleConfig { public: StyleConfig(QWidget *parent = nullptr) : QWidget(parent) { setupUi(this); } }; QString KCMStyle::defaultStyle() { #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) return QStringLiteral("breeze"); #else return QString(); // native style #endif } KCMStyle::KCMStyle( QWidget* parent, const QVariantList& ) : KCModule( parent ), appliedStyle(nullptr) { setQuickHelp( i18n("This module allows you to modify the visual appearance " "of applications' user interface elements.")); m_bStyleDirty= false; m_bEffectsDirty = false; KGlobal::dirs()->addResourceType("themes", "data", "kstyle/themes"); KAboutData *about = new KAboutData( QStringLiteral("kcmstyle"), i18n("Application Style"), QStringLiteral("1.0"), QString(), KAboutLicense::GPL, i18n("(c) 2002 Karol Szwed, Daniel Molkentin")); about->addAuthor(i18n("Karol Szwed"), QString(), QStringLiteral("gallium@kde.org")); about->addAuthor(i18n("Daniel Molkentin"), QString(), QStringLiteral("molkentin@kde.org")); setAboutData( about ); // Setup mainLayout mainLayout = new QVBoxLayout( this ); mainLayout->setContentsMargins(0, 0, 0, 0); styleConfig = new StyleConfig(); QHBoxLayout *previewLayout = new QHBoxLayout(); QGroupBox *gbPreview = new QGroupBox( i18n( "Preview" ) ); QHBoxLayout *previewLayoutInner = new QHBoxLayout(gbPreview); previewLayout->setContentsMargins(0, 0, 0, 0); previewLayoutInner->setContentsMargins(0, 0, 0, 0); previewLayout->addStretch(); previewLayout->addWidget( gbPreview ); previewLayout->addStretch(); stylePreview = new StylePreview( gbPreview ); previewLayoutInner->addWidget( stylePreview ); mainLayout->addWidget( styleConfig ); mainLayout->addLayout( previewLayout ); mainLayout->addStretch(); connect( styleConfig->comboStyle, SIGNAL(activated(int)), this, SLOT(styleChanged()) ); connect( styleConfig->comboStyle, SIGNAL(activated(int)), this, SLOT(updateConfigButton()) ); connect( styleConfig->pbConfigStyle, &QAbstractButton::clicked, this, &KCMStyle::styleSpecificConfig ); connect( styleConfig->comboStyle, SIGNAL(activated(int)), this, SLOT(setStyleDirty()) ); connect( styleConfig->cbIconsOnButtons, &QAbstractButton::toggled, this, &KCMStyle::setEffectsDirty ); connect( styleConfig->cbIconsInMenus, &QAbstractButton::toggled, this, &KCMStyle::setEffectsDirty ); connect( styleConfig->comboToolbarIcons, SIGNAL(activated(int)), this, SLOT(setEffectsDirty()) ); connect( styleConfig->comboSecondaryToolbarIcons, SIGNAL(activated(int)), this, SLOT(setEffectsDirty()) ); addWhatsThis(); } KCMStyle::~KCMStyle() { qDeleteAll(styleEntries); delete appliedStyle; } void KCMStyle::updateConfigButton() { if (!styleEntries[currentStyle()] || styleEntries[currentStyle()]->configPage.isEmpty()) { styleConfig->pbConfigStyle->setEnabled(false); return; } // We don't check whether it's loadable here - // lets us report an error and not waste time // loading things if the user doesn't click the button styleConfig->pbConfigStyle->setEnabled( true ); } void KCMStyle::styleSpecificConfig() { QString libname = styleEntries[currentStyle()]->configPage; KLibrary library(libname); if (!library.load()) { KMessageBox::detailedError(this, i18n("There was an error loading the configuration dialog for this style."), library.errorString(), i18n("Unable to Load Dialog")); return; } KLibrary::void_function_ptr allocPtr = library.resolveFunction("allocate_kstyle_config"); if (!allocPtr) { KMessageBox::detailedError(this, i18n("There was an error loading the configuration dialog for this style."), library.errorString(), i18n("Unable to Load Dialog")); return; } //Create the container dialog StyleConfigDialog* dial = new StyleConfigDialog(this, styleEntries[currentStyle()]->name); typedef QWidget*(* factoryRoutine)( QWidget* parent ); //Get the factory, and make the widget. factoryRoutine factory = (factoryRoutine)(allocPtr); //Grmbl. So here I am on my //"never use C casts" moralizing streak, and I find that one can't go void* -> function ptr //even with a reinterpret_cast. QWidget* pluginConfig = factory( dial ); //Insert it in... dial->setMainWidget( pluginConfig ); //..and connect it to the wrapper connect(pluginConfig, SIGNAL(changed(bool)), dial, SLOT(setDirty(bool))); connect(dial, SIGNAL(defaults()), pluginConfig, SLOT(defaults())); connect(dial, SIGNAL(save()), pluginConfig, SLOT(save())); if (dial->exec() == QDialog::Accepted && dial->isDirty() ) { // Force re-rendering of the preview, to apply settings switchStyle(currentStyle(), true); //For now, ask all KDE apps to recreate their styles to apply the setitngs KGlobalSettings::self()->emitChange(KGlobalSettings::StyleChanged); // We call setStyleDirty here to make sure we force style re-creation setStyleDirty(); } delete dial; } void KCMStyle::changeEvent( QEvent *event ) { KCModule::changeEvent( event ); if ( event->type() == QEvent::PaletteChange ) { // Force re-rendering of the preview, to apply new palette switchStyle(currentStyle(), true); } } void KCMStyle::load() { KConfig config( QStringLiteral("kdeglobals"), KConfig::FullConfig ); loadStyle( config ); loadEffects( config ); m_bStyleDirty= false; m_bEffectsDirty = false; //Enable/disable the button for the initial style updateConfigButton(); emit changed( false ); } void KCMStyle::save() { // Don't do anything if we don't need to. if ( !(m_bStyleDirty | m_bEffectsDirty ) ) return; // Save effects. KConfig _config(QStringLiteral("kdeglobals"), KConfig::NoGlobals); KConfigGroup config(&_config, "KDE"); // Effects page config.writeEntry( "ShowIconsOnPushButtons", styleConfig->cbIconsOnButtons->isChecked()); config.writeEntry( "ShowIconsInMenuItems", styleConfig->cbIconsInMenus->isChecked()); config.writeEntry("widgetStyle", currentStyle()); KConfigGroup toolbarStyleGroup(&_config, "Toolbar style"); toolbarStyleGroup.writeEntry("ToolButtonStyle", toolbarButtonText(styleConfig->comboToolbarIcons->currentIndex())); toolbarStyleGroup.writeEntry("ToolButtonStyleOtherToolbars", toolbarButtonText(styleConfig->comboSecondaryToolbarIcons->currentIndex())); _config.sync(); // Export the changes we made to qtrc, and update all qt-only // applications on the fly, ensuring that we still follow the user's // export fonts/colors settings. if (m_bStyleDirty || m_bEffectsDirty) // Export only if necessary { uint flags = KRdbExportQtSettings | KRdbExportGtkTheme; KConfig _kconfig( QStringLiteral("kcmdisplayrc"), KConfig::NoGlobals ); KConfigGroup kconfig(&_kconfig, "X11"); bool exportKDEColors = kconfig.readEntry("exportKDEColors", true); if (exportKDEColors) flags |= KRdbExportColors; runRdb( flags ); } // Now allow KDE apps to reconfigure themselves. if ( m_bStyleDirty ) KGlobalSettings::self()->emitChange(KGlobalSettings::StyleChanged); if ( m_bEffectsDirty ) { KGlobalSettings::self()->emitChange(KGlobalSettings::SettingsChanged, KGlobalSettings::SETTINGS_STYLE); // ##### FIXME - Doesn't apply all settings correctly due to bugs in // KApplication/KToolbar KGlobalSettings::self()->emitChange(KGlobalSettings::ToolbarStyleChanged); #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) // Send signal to all kwin instances QDBusMessage message = QDBusMessage::createSignal(QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"), QStringLiteral("reloadConfig")); QDBusConnection::sessionBus().send(message); #endif } // Clean up m_bStyleDirty = false; m_bEffectsDirty = false; emit changed( false ); } bool KCMStyle::findStyle( const QString& str, int& combobox_item ) { StyleEntry* se = styleEntries[str.toLower()]; QString name = se ? se->name : str; combobox_item = 0; //look up name for( int i = 0; i < styleConfig->comboStyle->count(); i++ ) { if ( styleConfig->comboStyle->itemText(i) == name ) { combobox_item = i; return true; } } return false; } void KCMStyle::defaults() { // Select default style int item = 0; bool found; found = findStyle( defaultStyle(), item ); if (!found) found = findStyle( QStringLiteral("oxygen"), item ); if (!found) found = findStyle( QStringLiteral("plastique"), item ); if (!found) found = findStyle( QStringLiteral("windows"), item ); if (!found) found = findStyle( QStringLiteral("platinum"), item ); if (!found) found = findStyle( QStringLiteral("motif"), item ); styleConfig->comboStyle->setCurrentIndex( item ); m_bStyleDirty = true; switchStyle( currentStyle() ); // make resets visible // Effects styleConfig->comboToolbarIcons->setCurrentIndex(toolbarButtonIndex(QStringLiteral("TextBesideIcon"))); styleConfig->comboSecondaryToolbarIcons->setCurrentIndex(toolbarButtonIndex(QStringLiteral("TextBesideIcon"))); styleConfig->cbIconsOnButtons->setChecked(true); styleConfig->cbIconsInMenus->setChecked(true); emit changed(true); emit updateConfigButton(); } void KCMStyle::setEffectsDirty() { m_bEffectsDirty = true; emit changed(true); } void KCMStyle::setStyleDirty() { m_bStyleDirty = true; emit changed(true); } // ---------------------------------------------------------------- // All the Style Switching / Preview stuff // ---------------------------------------------------------------- void KCMStyle::loadStyle( KConfig& config ) { styleConfig->comboStyle->clear(); // Create a dictionary of WidgetStyle to Name and Desc. mappings, // as well as the config page info qDeleteAll(styleEntries); styleEntries.clear(); QString strWidgetStyle; QStringList list = KGlobal::dirs()->findAllResources("themes", QStringLiteral("*.themerc"), KStandardDirs::Recursive | KStandardDirs::NoDuplicates); for (QStringList::iterator it = list.begin(); it != list.end(); ++it) { KConfig config( *it, KConfig::SimpleConfig); if ( !(config.hasGroup("KDE") && config.hasGroup("Misc")) ) continue; KConfigGroup configGroup = config.group("KDE"); strWidgetStyle = configGroup.readEntry("WidgetStyle"); if (strWidgetStyle.isNull()) continue; // We have a widgetstyle, so lets read the i18n entries for it... StyleEntry* entry = new StyleEntry; configGroup = config.group("Misc"); entry->name = configGroup.readEntry("Name"); entry->desc = configGroup.readEntry("Comment", i18n("No description available.")); entry->configPage = configGroup.readEntry("ConfigPage", QString()); // Check if this style should be shown configGroup = config.group("Desktop Entry"); entry->hidden = configGroup.readEntry("Hidden", false); // Insert the entry into our dictionary. styleEntries.insert(strWidgetStyle.toLower(), entry); } // Obtain all style names QStringList allStyles = QStyleFactory::keys(); // Get translated names, remove all hidden style entries. QStringList styles; StyleEntry* entry; for (QStringList::iterator it = allStyles.begin(); it != allStyles.end(); ++it) { QString id = (*it).toLower(); // Find the entry. if ( (entry = styleEntries[id]) != nullptr ) { // Do not add hidden entries if (entry->hidden) continue; styles += entry->name; nameToStyleKey[entry->name] = id; } else { styles += (*it); //Fall back to the key (but in original case) nameToStyleKey[*it] = id; } } // Sort the style list, and add it to the combobox styles.sort(); styleConfig->comboStyle->addItems( styles ); // Find out which style is currently being used KConfigGroup configGroup = config.group( "KDE" ); QString defaultStyle = KCMStyle::defaultStyle(); QString cfgStyle = configGroup.readEntry( "widgetStyle", defaultStyle ); // Select the current style // Do not use comboStyle->listBox() as this may be NULL for some styles when // they use QPopupMenus for the drop-down list! // ##### Since Trolltech likes to seemingly copy & paste code, // QStringList::findItem() doesn't have a Qt::StringComparisonMode field. // We roll our own (yuck) cfgStyle = cfgStyle.toLower(); int item = 0; for( int i = 0; i < styleConfig->comboStyle->count(); i++ ) { QString id = nameToStyleKey[styleConfig->comboStyle->itemText(i)]; item = i; if ( id == cfgStyle ) // ExactMatch break; else if ( id.contains( cfgStyle ) ) break; else if ( id.contains( QApplication::style()->metaObject()->className() ) ) break; item = 0; } styleConfig->comboStyle->setCurrentIndex( item ); m_bStyleDirty = false; switchStyle( currentStyle() ); // make resets visible } QString KCMStyle::currentStyle() { return nameToStyleKey[styleConfig->comboStyle->currentText()]; } void KCMStyle::styleChanged() { switchStyle( currentStyle() ); } void KCMStyle::switchStyle(const QString& styleName, bool force) { // Don't flicker the preview if the same style is chosen in the cb if (!force && appliedStyle && appliedStyle->objectName() == styleName) return; // Create an instance of the new style... QStyle* style = QStyleFactory::create(styleName); if (!style) return; // Prevent Qt from wrongly caching radio button images QPixmapCache::clear(); setStyleRecursive( stylePreview, style ); // this flickers, but reliably draws the widgets correctly. stylePreview->resize( stylePreview->sizeHint() ); delete appliedStyle; appliedStyle = style; } void KCMStyle::setStyleRecursive(QWidget* w, QStyle* s) { // Don't let broken styles kill the palette // for other styles being previewed. (e.g SGI style) w->setPalette(QPalette()); QPalette newPalette(KGlobalSettings::createApplicationPalette()); s->polish( newPalette ); w->setPalette(newPalette); // Apply the new style. w->setStyle(s); // Recursively update all children. const QObjectList children = w->children(); // Apply the style to each child widget. foreach (QObject* child, children) { if (child->isWidgetType()) setStyleRecursive((QWidget *) child, s); } } // ---------------------------------------------------------------- // All the Effects stuff // ---------------------------------------------------------------- QString KCMStyle::toolbarButtonText(int index) { switch (index) { case 1: return QStringLiteral("TextOnly"); case 2: return QStringLiteral("TextBesideIcon"); case 3: return QStringLiteral("TextUnderIcon"); default: break; } return QStringLiteral("NoText"); } int KCMStyle::toolbarButtonIndex(const QString &text) { if (text == QLatin1String("TextOnly")) { return 1; } else if (text == QLatin1String("TextBesideIcon")) { return 2; } else if (text == QLatin1String("TextUnderIcon")) { return 3; } return 0; } QString KCMStyle::menuBarStyleText(int index) { switch (index) { case 1: return QStringLiteral("Decoration"); case 2: return QStringLiteral("Widget"); } return QStringLiteral("InApplication"); } int KCMStyle::menuBarStyleIndex(const QString &text) { if (text == QLatin1String("Decoration")) { return 1; } else if (text == QLatin1String("Widget")) { return 2; } return 0; } void KCMStyle::loadEffects( KConfig& config ) { // KDE's Part via KConfig KConfigGroup configGroup = config.group("Toolbar style"); QString tbIcon = configGroup.readEntry("ToolButtonStyle", "TextBesideIcon"); styleConfig->comboToolbarIcons->setCurrentIndex(toolbarButtonIndex(tbIcon)); tbIcon = configGroup.readEntry("ToolButtonStyleOtherToolbars", "TextBesideIcon"); styleConfig->comboSecondaryToolbarIcons->setCurrentIndex(toolbarButtonIndex(tbIcon)); configGroup = config.group("KDE"); styleConfig->cbIconsOnButtons->setChecked(configGroup.readEntry("ShowIconsOnPushButtons", true)); styleConfig->cbIconsInMenus->setChecked(configGroup.readEntry("ShowIconsInMenuItems", true)); m_bEffectsDirty = false; } void KCMStyle::addWhatsThis() { stylePreview->setWhatsThis( i18n("This area shows a preview of the currently selected style " "without having to apply it to the whole desktop.") ); styleConfig->comboStyle->setWhatsThis( i18n("Here you can choose from a list of" " predefined widget styles (e.g. the way buttons are drawn) which" " may or may not be combined with a theme (additional information" " like a marble texture or a gradient).") ); styleConfig->cbIconsOnButtons->setWhatsThis( i18n( "If you enable this option, applications will " "show small icons alongside some important buttons.") ); styleConfig->cbIconsInMenus->setWhatsThis( i18n( "If you enable this option, applications will " "show small icons alongside most menu items.") ); styleConfig->comboToolbarIcons->setWhatsThis( i18n( "

No text: Shows only icons on toolbar buttons. " "Best option for low resolutions.

" "

Text only: Shows only text on toolbar buttons.

" "

Text beside icons: Shows icons and text on toolbar buttons. " "Text is aligned beside the icon.

" "Text below icons: Shows icons and text on toolbar buttons. " "Text is aligned below the icon.") ); } #include "kcmstyle.moc" // vim: set noet ts=4: