diff --git a/krusader/Konfigurator/kgcolors.cpp b/krusader/Konfigurator/kgcolors.cpp index 7ca1dbea..71d6c1f1 100644 --- a/krusader/Konfigurator/kgcolors.cpp +++ b/krusader/Konfigurator/kgcolors.cpp @@ -1,707 +1,709 @@ /***************************************************************************** * Copyright (C) 2004 Csaba Karai * * Copyright (C) 2004-2020 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "kgcolors.h" #include "../defaults.h" #include "../Panel/krcolorcache.h" #include "../Synchronizer/synchronizercolors.h" // QtCore #include #include // QtGui #include // QtWidgets #include #include #include #include #include #include #include #include KgColors::KgColors(bool first, QWidget* parent) : KonfiguratorPage(first, parent), offset(0), activeTabIdx(-1), inactiveTabIdx(-1), #ifdef SYNCHRONIZER_ENABLED synchronizerTabIdx(-1), #endif otherTabIdx(-1) { QWidget *innerWidget = new QFrame(this); setWidget(innerWidget); setWidgetResizable(true); auto *kgColorsLayout = new QGridLayout(innerWidget); kgColorsLayout->setSpacing(6); // -------------------------- GENERAL GROUPBOX ---------------------------------- QGroupBox *generalGrp = createFrame(i18n("General"), innerWidget); QGridLayout *generalGrid = createGridLayout(generalGrp); generalGrid->setSpacing(0); generalGrid->setContentsMargins(5, 5, 5, 5); KONFIGURATOR_CHECKBOX_PARAM generalSettings[] = // cfg_class cfg_name default text restart tooltip {{"Colors", "KDE Default", _KDEDefaultColors, i18n("Use the default KDE colors"), false, "

" + i18n("

Use KDE's global color configuration.

KDE System Settings -> Application Appearance -> Colors

") }, {"Colors", "Enable Alternate Background", _AlternateBackground, i18n("Use alternate background color"), false, i18n("

The background color and the alternate background color alternates line by line.

When you don't use the KDE default colors, you can configure the alternate colors in the colors box.

") }, {"Colors", "Show Current Item Always", _ShowCurrentItemAlways, i18n("Show current item even if not focused"), false, i18n("

Shows the last cursor position in the non active list panel.

This option is only available when you don't use the KDE default colors.

") }, {"Colors", "Dim Inactive Colors", _DimInactiveColors, i18n("Dim the colors of the inactive panel"), false, i18n("

The colors of the inactive panel are calculated by a dim color and a dim factor.

") } }; generals = createCheckBoxGroup(0, 2, generalSettings, sizeof(generalSettings) / sizeof(generalSettings[0]), generalGrp); generalGrid->addWidget(generals, 1, 0); generals->layout()->setSpacing(5); connect(generals->find("KDE Default"), &KonfiguratorCheckBox::stateChanged, this, &KgColors::slotDisable); connect(generals->find("Show Current Item Always"), &KonfiguratorCheckBox::stateChanged, this, &KgColors::slotDisable); connect(generals->find("Dim Inactive Colors"), &KonfiguratorCheckBox::stateChanged, this, &KgColors::slotDisable); kgColorsLayout->addWidget(generalGrp, 0 , 0, 1, 3); QWidget *hboxWidget = new QWidget(innerWidget); auto *hbox = new QHBoxLayout(hboxWidget); // -------------------------- COLORS GROUPBOX ---------------------------------- QGroupBox *colorsFrameGrp = createFrame(i18n("Colors"), hboxWidget); QGridLayout *colorsFrameGrid = createGridLayout(colorsFrameGrp); colorsFrameGrid->setSpacing(0); colorsFrameGrid->setContentsMargins(3, 3, 3, 3); colorTabWidget = new QTabWidget(colorsFrameGrp); colorsGrp = new QWidget(colorTabWidget); activeTabIdx = colorTabWidget->addTab(colorsGrp, i18n("Active")); colorsGrid = new QGridLayout(colorsGrp); colorsGrid->setSpacing(0); colorsGrid->setContentsMargins(2, 2, 2, 2); ADDITIONAL_COLOR transparent = { i18n("Transparent"), Qt::white, "transparent" }; QPalette p = QGuiApplication::palette(); addColorSelector("Foreground", i18n("Foreground:"), p.color(QPalette::Active, QPalette::Text)); addColorSelector("Directory Foreground", i18n("Folder foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as foreground")); addColorSelector("Executable Foreground", i18n("Executable foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as foreground")); addColorSelector("Symlink Foreground", i18n("Symbolic link foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as foreground")); addColorSelector("Invalid Symlink Foreground", i18n("Invalid symlink foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as foreground")); addColorSelector("Background", i18n("Background:"), p.color(QPalette::Active, QPalette::Base)); ADDITIONAL_COLOR sameAsBckgnd = { i18n("Same as background"), getColorSelector("Background")->getColor(), "Background" }; addColorSelector("Alternate Background", i18n("Alternate background:"), p.color(QPalette::Active, QPalette::AlternateBase), "", &sameAsBckgnd, 1); addColorSelector("Marked Foreground", i18n("Selected foreground:"), p.color(QPalette::Active, QPalette::HighlightedText), "", &transparent, 1); addColorSelector("Marked Background", i18n("Selected background:"), p.color(QPalette::Active, QPalette::Highlight), "", &sameAsBckgnd, 1); ADDITIONAL_COLOR sameAsAltern = { i18n("Same as alt. background"), getColorSelector("Alternate Background")->getColor(), "Alternate Background" }; addColorSelector("Alternate Marked Background", i18n("Alternate selected background:"), getColorSelector("Marked Background")->getColor(), i18n("Same as selected background"), &sameAsAltern, 1); addColorSelector("Current Foreground", i18n("Current foreground:"), Qt::white, i18n("Not used")); ADDITIONAL_COLOR sameAsMarkedForegnd = { i18n("Same as selected foreground"), getColorSelector("Marked Foreground")->getColor(), "Marked Foreground" }; addColorSelector("Marked Current Foreground", i18n("Selected current foreground:"), Qt::white, i18n("Not used"), &sameAsMarkedForegnd, 1); addColorSelector("Current Background", i18n("Current background:"), Qt::white, i18n("Not used"), &sameAsBckgnd, 1); + addColorSelector("Rename Foreground", i18n("Rename foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as foreground")); + addColorSelector("Rename Background", i18n("Rename background:"), getColorSelector("Background")->getColor(), i18n("Same as background")); colorsGrid->addWidget(createSpacer(colorsGrp), itemList.count() - offset, 1); connect(getColorSelector("Foreground"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotForegroundChanged); connect(getColorSelector("Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotBackgroundChanged); connect(getColorSelector("Alternate Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotAltBackgroundChanged); connect(getColorSelector("Marked Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotMarkedBackgroundChanged); inactiveColorStack = new QStackedWidget(colorTabWidget); inactiveTabIdx = colorTabWidget->addTab(inactiveColorStack, i18n("Inactive")); colorsGrp = normalInactiveWidget = new QWidget(inactiveColorStack); colorsGrid = new QGridLayout(normalInactiveWidget); colorsGrid->setSpacing(0); colorsGrid->setContentsMargins(2, 2, 2, 2); offset = endOfActiveColors = itemList.count(); addColorSelector("Inactive Foreground", i18n("Foreground:"), getColorSelector("Foreground")->getColor(), i18n("Same as active")); ADDITIONAL_COLOR sameAsInactForegnd = { i18n("Same as foreground"), getColorSelector("Inactive Foreground")->getColor(), "Inactive Foreground" }; addColorSelector("Inactive Directory Foreground", i18n("Folder foreground:"), getColorSelector("Directory Foreground")->getColor(), i18n("Same as active"), &sameAsInactForegnd, 1); addColorSelector("Inactive Executable Foreground", i18n("Executable foreground:"), getColorSelector("Executable Foreground")->getColor(), i18n("Same as active"), &sameAsInactForegnd, 1); addColorSelector("Inactive Symlink Foreground", i18n("Symbolic link foreground:"), getColorSelector("Symlink Foreground")->getColor(), i18n("Same as active"), &sameAsInactForegnd, 1); addColorSelector("Inactive Invalid Symlink Foreground", i18n("Invalid symlink foreground:"), getColorSelector("Invalid Symlink Foreground")->getColor(), i18n("Same as active"), &sameAsInactForegnd, 1); addColorSelector("Inactive Background", i18n("Background:"), getColorSelector("Background")->getColor(), i18n("Same as active")); ADDITIONAL_COLOR sameAsInactBckgnd = { i18n("Same as background"), getColorSelector("Inactive Background")->getColor(), "Inactive Background" }; addColorSelector("Inactive Alternate Background", i18n("Alternate background:"), getColorSelector("Alternate Background")->getColor(), i18n("Same as active"), &sameAsInactBckgnd, 1); addColorSelector("Inactive Marked Foreground", i18n("Selected foreground:"), getColorSelector("Marked Foreground")->getColor(), i18n("Same as active"), &transparent, 1); addColorSelector("Inactive Marked Background", i18n("Selected background:"), getColorSelector("Marked Background")->getColor(), i18n("Same as active"), &sameAsInactBckgnd, 1); ADDITIONAL_COLOR sameAsInactAltern[] = {{ i18n("Same as alt. background"), getColorSelector("Inactive Alternate Background")->getColor(), "Inactive Alternate Background" }, { i18n("Same as selected background"), getColorSelector("Inactive Marked Background")->getColor(), "Inactive Marked Background" } }; addColorSelector("Inactive Alternate Marked Background", i18n("Alternate selected background:"), getColorSelector("Alternate Marked Background")->getColor(), i18n("Same as active"), sameAsInactAltern, 2); addColorSelector("Inactive Current Foreground", i18n("Current foreground:"), getColorSelector("Current Foreground")->getColor(), i18n("Same as active")); ADDITIONAL_COLOR sameAsInactMarkedForegnd = { i18n("Same as selected foreground"), getColorSelector("Inactive Marked Foreground")->getColor(), "Inactive Marked Foreground" }; addColorSelector("Inactive Marked Current Foreground", i18n("Selected current foreground:"), getColorSelector("Marked Current Foreground")->getColor(), i18n("Same as active"), &sameAsInactMarkedForegnd, 1); addColorSelector("Inactive Current Background", i18n("Current background:"), getColorSelector("Current Background")->getColor(), i18n("Same as active"), &sameAsInactBckgnd, 1); colorsGrid->addWidget(createSpacer(normalInactiveWidget), itemList.count() - offset, 1); connect(getColorSelector("Inactive Foreground"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotInactiveForegroundChanged); connect(getColorSelector("Inactive Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotInactiveBackgroundChanged); connect(getColorSelector("Inactive Alternate Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotInactiveAltBackgroundChanged); connect(getColorSelector("Inactive Marked Background"), &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotInactiveMarkedBackgroundChanged); offset = endOfPanelColors = itemList.count(); inactiveColorStack->addWidget(normalInactiveWidget); colorsGrp = dimmedInactiveWidget = new QWidget(inactiveColorStack); colorsGrid = new QGridLayout(dimmedInactiveWidget); colorsGrid->setSpacing(0); colorsGrid->setContentsMargins(2, 2, 2, 2); addColorSelector("Dim Target Color", i18n("Dim target color:"), Qt::black); int index = itemList.count() - offset; QLabel *spinBoxLabel = addLabel(colorsGrid, index, 0, i18n("Dim factor:"), colorsGrp); labelList.append(spinBoxLabel); dimFactor = createSpinBox("Colors", "Dim Factor", 80, 0, 100, spinBoxLabel, colorsGrp); dimFactor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); colorsGrid->addWidget(dimFactor, index++, 1); colorsGrid->addWidget(createSpacer(dimmedInactiveWidget), itemList.count() + 1 - offset, 1); inactiveColorStack->addWidget(dimmedInactiveWidget); inactiveColorStack->setCurrentWidget(normalInactiveWidget); ADDITIONAL_COLOR KDEDefaultBase = { i18n("KDE default"), p.color(QPalette::Active, QPalette::Base), "KDE default" }; ADDITIONAL_COLOR KDEDefaultFore = { i18n("KDE default"), p.color(QPalette::Active, QPalette::Text), "KDE default" }; #ifdef SYNCHRONIZER_ENABLED colorsGrp = new QWidget(colorTabWidget); synchronizerTabIdx = colorTabWidget->addTab(colorsGrp, i18n("Synchronizer")); colorsGrid = new QGridLayout(colorsGrp); colorsGrid->setSpacing(0); colorsGrid->setContentsMargins(2, 2, 2, 2); offset = endOfPanelColors = itemList.count(); DECLARE_SYNCHRONIZER_BACKGROUND_DEFAULTS; DECLARE_SYNCHRONIZER_FOREGROUND_DEFAULTS; addColorSelector("Synchronizer Equals Foreground", i18n("Equals foreground:"), SYNCHRONIZER_FOREGROUND_DEFAULTS[0], QString(), &KDEDefaultFore, 1); addColorSelector("Synchronizer Equals Background", i18n("Equals background:"), SYNCHRONIZER_BACKGROUND_DEFAULTS[0], QString(), &KDEDefaultBase, 1); addColorSelector("Synchronizer Differs Foreground", i18n("Differing foreground:"), SYNCHRONIZER_FOREGROUND_DEFAULTS[1], QString(), &KDEDefaultFore, 1); addColorSelector("Synchronizer Differs Background", i18n("Differing background:"), SYNCHRONIZER_BACKGROUND_DEFAULTS[1], QString(), &KDEDefaultBase, 1); addColorSelector("Synchronizer LeftCopy Foreground", i18n("Copy to left foreground:"), SYNCHRONIZER_FOREGROUND_DEFAULTS[2], QString(), &KDEDefaultFore, 1); addColorSelector("Synchronizer LeftCopy Background", i18n("Copy to left background:"), SYNCHRONIZER_BACKGROUND_DEFAULTS[2], QString(), &KDEDefaultBase, 1); addColorSelector("Synchronizer RightCopy Foreground", i18n("Copy to right foreground:"), SYNCHRONIZER_FOREGROUND_DEFAULTS[3], QString(), &KDEDefaultFore, 1); addColorSelector("Synchronizer RightCopy Background", i18n("Copy to right background:"), SYNCHRONIZER_BACKGROUND_DEFAULTS[3], QString(), &KDEDefaultBase, 1); addColorSelector("Synchronizer Delete Foreground", i18n("Delete foreground:"), SYNCHRONIZER_FOREGROUND_DEFAULTS[4], QString(), &KDEDefaultFore, 1); addColorSelector("Synchronizer Delete Background", i18n("Delete background:"), SYNCHRONIZER_BACKGROUND_DEFAULTS[4], QString(), &KDEDefaultBase, 1); colorsGrid->addWidget(createSpacer(colorsGrp), itemList.count() - offset, 1); #endif colorsGrp = new QWidget(colorTabWidget); otherTabIdx = colorTabWidget->addTab(colorsGrp, i18n("Other")); colorsGrid = new QGridLayout(colorsGrp); colorsGrid->setSpacing(0); colorsGrid->setContentsMargins(2, 2, 2, 2); offset = endOfPanelColors = itemList.count(); addColorSelector("Quicksearch Match Foreground", i18n("Quicksearch, match foreground:"), Qt::black, QString(), &KDEDefaultFore, 1); addColorSelector("Quicksearch Match Background", i18n("Quicksearch, match background:"), QColor(192, 255, 192), QString(), &KDEDefaultBase, 1); addColorSelector("Quicksearch Non-match Foreground", i18n("Quicksearch, non-match foreground:"), Qt::black, QString(), &KDEDefaultFore, 1); addColorSelector("Quicksearch Non-match Background", i18n("Quicksearch, non-match background:"), QColor(255, 192, 192), QString(), &KDEDefaultBase, 1); ADDITIONAL_COLOR KDEDefaultWindowFore = { i18n("KDE default"), p.color(QPalette::Active, QPalette::WindowText), "KDE default" }; ADDITIONAL_COLOR KDEDefaultWindowBack = { i18n("KDE default"), p.color(QPalette::Active, QPalette::Window), "KDE default" }; addColorSelector("Statusbar Foreground Active", i18n("Statusbar, active foreground:"), p.color(QPalette::Active, QPalette::HighlightedText), QString(), &KDEDefaultWindowFore, 1); addColorSelector("Statusbar Background Active", i18n("Statusbar, active background:"), p.color(QPalette::Active, QPalette::Highlight), QString(), &KDEDefaultWindowBack, 1); addColorSelector("Statusbar Foreground Inactive", i18n("Statusbar, inactive foreground:"), p.color(QPalette::Inactive, QPalette::Text), QString(), &KDEDefaultWindowFore, 1); addColorSelector("Statusbar Background Inactive", i18n("Statusbar, inactive background:"), p.color(QPalette::Inactive, QPalette::Base), QString(), &KDEDefaultWindowBack, 1); colorsGrid->addWidget(createSpacer(colorsGrp), itemList.count() - offset, 1); colorsFrameGrid->addWidget(colorTabWidget, 0, 0); hbox->addWidget(colorsFrameGrp); // -------------------------- PREVIEW GROUPBOX ---------------------------------- previewGrp = createFrame(i18n("Preview"), hboxWidget); previewGrid = createGridLayout(previewGrp); preview = new KrTreeWidget(previewGrp); preview->setBackgroundRole(QPalette::Window); preview->setAutoFillBackground(true); QStringList labels; labels << i18n("Colors"); preview->setHeaderLabels(labels); preview->header()->setSortIndicatorShown(false); preview->setSortingEnabled(false); preview->setEnabled(false); previewGrid->addWidget(preview, 0 , 0); hbox->addWidget(previewGrp); connect(generals->find("Enable Alternate Background"), &KonfiguratorCheckBox::stateChanged, this, &KgColors::generatePreview); connect(colorTabWidget, &QTabWidget::currentChanged, this, &KgColors::generatePreview); connect(dimFactor, QOverload::of(&KonfiguratorSpinBox::valueChanged), this, &KgColors::generatePreview); kgColorsLayout->addWidget(hboxWidget, 1 , 0, 1, 3); importBtn = new QPushButton(i18n("Import color-scheme"), innerWidget); kgColorsLayout->addWidget(importBtn, 2, 0); exportBtn = new QPushButton(i18n("Export color-scheme"), innerWidget); kgColorsLayout->addWidget(exportBtn, 2, 1); kgColorsLayout->addWidget(createSpacer(innerWidget), 2, 2); connect(importBtn, &QPushButton::clicked, this, &KgColors::slotImportColors); connect(exportBtn, &QPushButton::clicked, this, &KgColors::slotExportColors); slotDisable(); } int KgColors::addColorSelector(const QString& cfgName, QString name, QColor defaultValue, const QString& dfltName, ADDITIONAL_COLOR *addColor, int addColNum) { int index = itemList.count() - offset; labelList.append(addLabel(colorsGrid, index, 0, std::move(name), colorsGrp)); KonfiguratorColorChooser *chooser = createColorChooser("Colors", cfgName, std::move(defaultValue), colorsGrp, false, addColor, addColNum); chooser->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); if (!dfltName.isEmpty()) chooser->setDefaultText(dfltName); colorsGrid->addWidget(chooser, index, 1); connect(chooser, &KonfiguratorColorChooser::colorChanged, this, &KgColors::generatePreview); if (!offset) connect(chooser, &KonfiguratorColorChooser::colorChanged, this, &KgColors::slotActiveChanged); itemList.append(chooser); itemNames.append(cfgName); return index; } KonfiguratorColorChooser *KgColors::getColorSelector(const QString& name) { QList::iterator it; int position = 0; for (it = itemNames.begin(); it != itemNames.end(); it++, position++) if (*it == name) return itemList.at(position); return nullptr; } QLabel *KgColors::getSelectorLabel(const QString& name) { QList::iterator it; int position = 0; for (it = itemNames.begin(); it != itemNames.end(); it++, position++) if (*it == name) return labelList.at(position); return nullptr; } void KgColors::slotDisable() { bool enabled = generals->find("KDE Default")->isChecked(); importBtn->setEnabled(!enabled); exportBtn->setEnabled(!enabled); for (int i = 0; i < labelList.count() && i < endOfPanelColors ; i++) labelList.at(i)->setEnabled(!enabled); for (int j = 0; j < itemList.count() && j < endOfPanelColors ; j++) itemList.at(j)->setEnabled(!enabled); generals->find("Enable Alternate Background")->setEnabled(enabled); generals->find("Show Current Item Always")->setEnabled(!enabled); generals->find("Dim Inactive Colors")->setEnabled(!enabled); bool dimmed = !enabled && generals->find("Dim Inactive Colors")->isChecked(); if (dimmed) inactiveColorStack->setCurrentWidget(dimmedInactiveWidget); else inactiveColorStack->setCurrentWidget(normalInactiveWidget); enabled = enabled || !generals->find("Show Current Item Always")->isChecked(); getColorSelector("Inactive Current Foreground")->setEnabled(!enabled); getColorSelector("Inactive Current Background")->setEnabled(!enabled); generatePreview(); } void KgColors::slotActiveChanged() { for (int i = 0; i != endOfActiveColors; i++) itemList.at(endOfActiveColors + i)->setDefaultColor(itemList.at(i)->getColor()); } void KgColors::slotForegroundChanged() { QColor color = getColorSelector("Foreground")->getColor(); getColorSelector("Directory Foreground")->setDefaultColor(color); getColorSelector("Executable Foreground")->setDefaultColor(color); getColorSelector("Symlink Foreground")->setDefaultColor(color); getColorSelector("Invalid Symlink Foreground")->setDefaultColor(color); } void KgColors::slotBackgroundChanged() { QColor color = getColorSelector("Background")->getColor(); getColorSelector("Alternate Background")->changeAdditionalColor(0, color); getColorSelector("Marked Background")->changeAdditionalColor(0, color); getColorSelector("Current Background")->changeAdditionalColor(0, color); } void KgColors::slotAltBackgroundChanged() { QColor color = getColorSelector("Alternate Background")->getColor(); getColorSelector("Alternate Marked Background")->changeAdditionalColor(0, color); } void KgColors::slotMarkedBackgroundChanged() { QColor color = getColorSelector("Marked Background")->getColor(); getColorSelector("Alternate Marked Background")->setDefaultColor(color); } void KgColors::slotInactiveForegroundChanged() { QColor color = getColorSelector("Inactive Foreground")->getColor(); getColorSelector("Inactive Directory Foreground")->changeAdditionalColor(0, color); getColorSelector("Inactive Executable Foreground")->changeAdditionalColor(0, color); getColorSelector("Inactive Symlink Foreground")->changeAdditionalColor(0, color); getColorSelector("Inactive Invalid Symlink Foreground")->changeAdditionalColor(0, color); } void KgColors::slotInactiveBackgroundChanged() { QColor color = getColorSelector("Inactive Background")->getColor(); getColorSelector("Inactive Alternate Background")->changeAdditionalColor(0, color); getColorSelector("Inactive Marked Background")->changeAdditionalColor(0, color); getColorSelector("Inactive Current Background")->changeAdditionalColor(0, color); } void KgColors::slotInactiveAltBackgroundChanged() { QColor color = getColorSelector("Inactive Alternate Background")->getColor(); getColorSelector("Inactive Alternate Marked Background")->changeAdditionalColor(0, color); } void KgColors::slotInactiveMarkedBackgroundChanged() { QColor color = getColorSelector("Inactive Marked Background")->getColor(); getColorSelector("Inactive Alternate Marked Background")->changeAdditionalColor(1, color); } void KgColors::setColorWithDimming(PreviewItem * item, QColor foreground, QColor background, bool dimmed) { if (dimmed && dimFactor->value() < 100) { int dim = dimFactor->value(); QColor dimColor = getColorSelector("Dim Target Color")->getColor(); foreground = QColor((dimColor.red() * (100 - dim) + foreground.red() * dim) / 100, (dimColor.green() * (100 - dim) + foreground.green() * dim) / 100, (dimColor.blue() * (100 - dim) + foreground.blue() * dim) / 100); background = QColor((dimColor.red() * (100 - dim) + background.red() * dim) / 100, (dimColor.green() * (100 - dim) + background.green() * dim) / 100, (dimColor.blue() * (100 - dim) + background.blue() * dim) / 100); } item->setColor(foreground, background); } void KgColors::generatePreview() { const int currentPage = colorTabWidget->currentIndex(); preview->clear(); if (currentPage == activeTabIdx || currentPage == inactiveTabIdx) { PreviewItem *pwMarkCur = new PreviewItem(preview, i18n("Selected + Current")); PreviewItem *pwMark2 = new PreviewItem(preview, i18n("Selected 2")); PreviewItem *pwMark1 = new PreviewItem(preview, i18n("Selected 1")); PreviewItem *pwCurrent = new PreviewItem(preview, i18n("Current")); PreviewItem *pwInvLink = new PreviewItem(preview, i18n("Invalid symlink")); PreviewItem *pwSymLink = new PreviewItem(preview, i18n("Symbolic link")); PreviewItem *pwApp = new PreviewItem(preview, i18n("Application")); PreviewItem *pwFile = new PreviewItem(preview, i18n("File")); PreviewItem *pwDir = new PreviewItem(preview, i18n("Folder")); bool isActive = currentPage == 0; // create local color cache instance, which does NOT affect the color cache instance using to paint the panels KrColorCache colCache; // create local color settings instance, which initially contains the settings from krConfig KrColorSettings colorSettings; // copy over local settings to color settings instance, which does not affect the persisted krConfig settings QList names = KrColorSettings::getColorNames(); for (auto & name : names) { KonfiguratorColorChooser * chooser = getColorSelector(name); if (!chooser) continue; colorSettings.setColorTextValue(name, chooser->getValue()); if (chooser->isValueRGB()) colorSettings.setColorValue(name, chooser->getColor()); else colorSettings.setColorValue(name, QColor()); } colorSettings.setBoolValue("KDE Default", generals->find("KDE Default")->isChecked()); colorSettings.setBoolValue("Enable Alternate Background", generals->find("Enable Alternate Background")->isChecked()); colorSettings.setBoolValue("Show Current Item Always", generals->find("Show Current Item Always")->isChecked()); colorSettings.setBoolValue("Dim Inactive Colors", generals->find("Dim Inactive Colors")->isChecked()); colorSettings.setNumValue("Dim Factor", dimFactor->value()); // let the color cache use the local color settings colCache.setColors(colorSettings); // ask the local color cache for certain color groups and use them to color the preview KrColorGroup cg; // setting the background color colCache.getColors(cg, KrColorItemType(KrColorItemType::File, false, isActive, false, false)); QPalette pal = preview->palette(); pal.setColor(QPalette::Base, cg.background()); preview->setPalette(pal); colCache.getColors(cg, KrColorItemType(KrColorItemType::Directory, false, isActive, false, false)); pwDir->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::File, true, isActive, false, false)); pwFile->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::Executable, false, isActive, false, false)); pwApp->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::Symlink, true, isActive, false, false)); pwSymLink->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::InvalidSymlink, false, isActive, false, false)); pwInvLink->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::File, true, isActive, true, false)); pwCurrent->setColor(cg.text(), cg.background()); colCache.getColors(cg, KrColorItemType(KrColorItemType::File, false, isActive, false, true)); pwMark1->setColor(cg.highlightedText(), cg.highlight()); colCache.getColors(cg, KrColorItemType(KrColorItemType::File, true, isActive, false, true)); pwMark2->setColor(cg.highlightedText(), cg.highlight()); colCache.getColors(cg, KrColorItemType(KrColorItemType::File, false, isActive, true, true)); pwMarkCur->setColor(cg.highlightedText(), cg.highlight()); } #ifdef SYNCHRONIZER_ENABLED else if (currentPage == synchronizerTabIdx) { PreviewItem *pwDelete = new PreviewItem(preview, i18n("Delete")); PreviewItem *pwRightCopy = new PreviewItem(preview, i18n("Copy to right")); PreviewItem *pwLeftCopy = new PreviewItem(preview, i18n("Copy to left")); PreviewItem *pwDiffers = new PreviewItem(preview, i18n("Differing")); PreviewItem *pwEquals = new PreviewItem(preview, i18n("Equals")); pwEquals->setColor(getColorSelector("Synchronizer Equals Foreground")->getColor(), getColorSelector("Synchronizer Equals Background")->getColor()); pwDiffers->setColor(getColorSelector("Synchronizer Differs Foreground")->getColor(), getColorSelector("Synchronizer Differs Background")->getColor()); pwLeftCopy->setColor(getColorSelector("Synchronizer LeftCopy Foreground")->getColor(), getColorSelector("Synchronizer LeftCopy Background")->getColor()); pwRightCopy->setColor(getColorSelector("Synchronizer RightCopy Foreground")->getColor(), getColorSelector("Synchronizer RightCopy Background")->getColor()); pwDelete->setColor(getColorSelector("Synchronizer Delete Foreground")->getColor(), getColorSelector("Synchronizer Delete Background")->getColor()); } #endif else if (currentPage == otherTabIdx) { PreviewItem *pwNonMatch = new PreviewItem(preview, i18n("Quicksearch non-match")); PreviewItem *pwMatch = new PreviewItem(preview, i18n("Quicksearch match")); pwMatch->setColor(getColorSelector("Quicksearch Match Foreground")->getColor(), getColorSelector("Quicksearch Match Background")->getColor()); pwNonMatch->setColor(getColorSelector("Quicksearch Non-match Foreground")->getColor(), getColorSelector("Quicksearch Non-match Background")->getColor()); PreviewItem *pwStatusActive = new PreviewItem(preview, i18n("Statusbar active")); PreviewItem *pwStatusInactive = new PreviewItem(preview, i18n("Statusbar inactive")); pwStatusActive->setColor(getColorSelector("Statusbar Foreground Active")->getColor(), getColorSelector("Statusbar Background Active")->getColor()); pwStatusInactive->setColor(getColorSelector("Statusbar Foreground Inactive")->getColor(), getColorSelector("Statusbar Background Inactive")->getColor()); } } bool KgColors::apply() { bool result = KonfiguratorPage::apply(); KrColorCache::getColorCache().refreshColors(); return result; } void KgColors::slotImportColors() { // find $KDEDIR/share/apps/krusader QString basedir= QStandardPaths::locate(QStandardPaths::DataLocation, QStringLiteral("total_commander.keymap")); basedir = QFileInfo(basedir).absolutePath(); // let the user select a file to load QString file = QFileDialog::getOpenFileName(nullptr, i18n("Select a color-scheme file"), basedir, QStringLiteral("*.color")); if (file.isEmpty()) { return; } QFile f(file); if (!f.open(QIODevice::ReadOnly)) { KMessageBox::error(this, i18n("Error: unable to read from file"), i18n("Error")); return; } QDataStream stream(&f); // ok, import away deserialize(stream); generatePreview(); } void KgColors::slotExportColors() { QString file = QFileDialog::getSaveFileName(nullptr, i18n("Select a color scheme file"), QString(), QStringLiteral("*")); if (file.isEmpty()) { return; } QFile f(file); if (f.exists() && KMessageBox::warningContinueCancel(this, i18n("File %1 already exists. Are you sure you want to overwrite it?", file), i18n("Warning"), KStandardGuiItem::overwrite()) != KMessageBox::Continue) return; if (!f.open(QIODevice::WriteOnly)) { KMessageBox::error(this, i18n("Error: unable to write to file"), i18n("Error")); return; } QDataStream stream(&f); serialize(stream); } void KgColors::serialize(QDataStream & stream) { serializeItem(stream, "Alternate Background"); serializeItem(stream, "Alternate Marked Background"); serializeItem(stream, "Background"); serializeItem(stream, "Current Background"); serializeItem(stream, "Current Foreground"); serializeItem(stream, "Enable Alternate Background"); serializeItem(stream, "Foreground"); serializeItem(stream, "Directory Foreground"); serializeItem(stream, "Executable Foreground"); serializeItem(stream, "Symlink Foreground"); serializeItem(stream, "Invalid Symlink Foreground"); serializeItem(stream, "Inactive Alternate Background"); serializeItem(stream, "Inactive Alternate Marked Background"); serializeItem(stream, "Inactive Background"); serializeItem(stream, "Inactive Current Foreground"); serializeItem(stream, "Inactive Current Background"); serializeItem(stream, "Inactive Marked Background"); serializeItem(stream, "Inactive Marked Current Foreground"); serializeItem(stream, "Inactive Marked Foreground"); serializeItem(stream, "Inactive Foreground"); serializeItem(stream, "Inactive Directory Foreground"); serializeItem(stream, "Inactive Executable Foreground"); serializeItem(stream, "Inactive Symlink Foreground"); serializeItem(stream, "Inactive Invalid Symlink Foreground"); serializeItem(stream, "Dim Inactive Colors"); serializeItem(stream, "Dim Target Color"); serializeItem(stream, "Dim Factor"); serializeItem(stream, "KDE Default"); serializeItem(stream, "Marked Background"); serializeItem(stream, "Marked Current Foreground"); serializeItem(stream, "Marked Foreground"); serializeItem(stream, "Show Current Item Always"); #ifdef SYNCHRONIZER_ENABLED serializeItem(stream, "Synchronizer Equals Foreground"); serializeItem(stream, "Synchronizer Equals Background"); serializeItem(stream, "Synchronizer Differs Foreground"); serializeItem(stream, "Synchronizer Differs Background"); serializeItem(stream, "Synchronizer LeftCopy Foreground"); serializeItem(stream, "Synchronizer LeftCopy Background"); serializeItem(stream, "Synchronizer RightCopy Foreground"); serializeItem(stream, "Synchronizer RightCopy Background"); serializeItem(stream, "Synchronizer Delete Foreground"); serializeItem(stream, "Synchronizer Delete Background"); #endif serializeItem(stream, "Quicksearch Match Foreground"); serializeItem(stream, "Quicksearch Match Background"); serializeItem(stream, "Quicksearch Non-match Foreground"); serializeItem(stream, "Quicksearch Non-match Background"); serializeItem(stream, "Statusbar Foreground Active"); serializeItem(stream, "Statusbar Background Active"); serializeItem(stream, "Statusbar Foreground Inactive"); serializeItem(stream, "Statusbar Background Inactive"); stream << QString("") << QString(""); } void KgColors::deserialize(QDataStream & stream) { for (;;) { QString name; QString value; stream >> name >> value; if (name.isEmpty()) break; if (name == "KDE Default" || name == "Enable Alternate Background" || name == "Show Current Item Always" || name == "Dim Inactive Colors") { bool bValue = false; value = value.toLower(); if (value == "true" || value == "yes" || value == "on" || value == "1") bValue = true; generals->find(name)->setChecked(bValue); continue; } if (name == "Dim Factor") { dimFactor->setValue(value.toInt()); continue; } KonfiguratorColorChooser *selector = getColorSelector(name); if (selector == nullptr) break; selector->setValue(value); } } void KgColors::serializeItem(class QDataStream & stream, const char * name) { stream << QString(name); if (strcmp(name, "KDE Default") == 0 || strcmp(name, "Enable Alternate Background") == 0 || strcmp(name, "Show Current Item Always") == 0 || strcmp(name, "Dim Inactive Colors") == 0) { bool bValue = generals->find(name)->isChecked(); stream << QString(bValue ? "true" : "false"); } else if (strcmp(name, "Dim Factor") == 0) stream << QString::number(dimFactor->value()); else { KonfiguratorColorChooser *selector = getColorSelector(name); stream << selector->getValue(); } } diff --git a/krusader/Panel/PanelView/krviewitemdelegate.cpp b/krusader/Panel/PanelView/krviewitemdelegate.cpp index 38273f1e..144a3317 100644 --- a/krusader/Panel/PanelView/krviewitemdelegate.cpp +++ b/krusader/Panel/PanelView/krviewitemdelegate.cpp @@ -1,153 +1,168 @@ /***************************************************************************** * Copyright (C) 2009 Csaba Karai * * Copyright (C) 2009-2020 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krviewitemdelegate.h" #include "krviewproperties.h" #include "../krglobal.h" #include "../listpanel.h" +#include "../krcolorcache.h" // QtGui #include #include // QtWidgets #include #include #include #include KrViewItemDelegate::KrViewItemDelegate(QObject *parent) : QItemDelegate(parent), _currentlyEdited(-1), _dontDraw(false) {} void KrViewItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { QStyleOptionViewItem opt = option; opt.state &= ~QStyle::State_Selected; _dontDraw = (_currentlyEdited == index.row()) && (index.column() == KrViewProperties::Ext); QItemDelegate::paint(painter, opt, index); } void KrViewItemDelegate::drawDisplay(QPainter * painter, const QStyleOptionViewItem & option, const QRect & rect, const QString & text) const { if (!_dontDraw) QItemDelegate::drawDisplay(painter, option, rect, text); } QWidget * KrViewItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &sovi, const QModelIndex &index) const { _currentlyEdited = index.row(); return QItemDelegate::createEditor(parent, sovi, index); } void KrViewItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QItemDelegate::setEditorData(editor, index); auto *lineEdit = qobject_cast (editor); if (lineEdit) { KConfigGroup gl(krConfig, "Look&Feel"); QFont font = index.data(Qt::FontRole).value(); lineEdit->setFont(font); if (gl.readEntry("Rename Selects Extension", true)) lineEdit->selectAll(); else { QString nameWithoutExt = index.data(Qt::UserRole).toString(); lineEdit->deselect(); lineEdit->setSelection(0, nameWithoutExt.length()); } + + KrColorSettings colSettings; + + if (!colSettings.getBoolValue("KDE Default")) { + QPalette renamePalette = lineEdit->palette(); + + if (!colSettings.getColorTextValue("Rename Foreground").isEmpty()) + renamePalette.setColor(QPalette::Text, colSettings.getColorValue("Rename Foreground")); + + if (!colSettings.getColorTextValue("Rename Background").isEmpty()) + renamePalette.setColor(QPalette::Base, colSettings.getColorValue("Rename Background")); + + lineEdit->setPalette(renamePalette); + } } } QSize KrViewItemDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const { QSize size = QItemDelegate::sizeHint(option, index); if (size.isEmpty()) { // prevent items without text from bloating the view vertically return QSize(0, 0); } return size; } bool KrViewItemDelegate::eventFilter(QObject *object, QEvent *event) { QWidget *editor = qobject_cast(object); if (!editor) return false; if (event->type() == QEvent::KeyPress) { switch (dynamic_cast(event)->key()) { case Qt::Key_Tab: case Qt::Key_Backtab: _currentlyEdited = -1; emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache); return true; case Qt::Key_Enter: case Qt::Key_Return: if (auto *e = qobject_cast(editor)) { if (!e->hasAcceptableInput()) return true; event->accept(); emit commitData(editor); emit closeEditor(editor, QAbstractItemDelegate::SubmitModelCache); _currentlyEdited = -1; return true; } return false; case Qt::Key_Escape: event->accept(); // don't commit data _currentlyEdited = -1; emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache); break; default: return false; } if (editor->parentWidget()) editor->parentWidget()->setFocus(); return true; } else if (event->type() == QEvent::FocusOut) { if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) { QWidget *w = QApplication::focusWidget(); while (w) { // don't worry about focus changes internally in the editor if (w == editor) return false; w = w->parentWidget(); } // Opening a modal dialog will start a new eventloop // that will process the deleteLater event. if (QApplication::activeModalWidget() && !QApplication::activeModalWidget()->isAncestorOf(editor) && qobject_cast(QApplication::activeModalWidget())) return false; _currentlyEdited = -1; // manually set focus back to panel after rename canceled by focusing another window ACTIVE_PANEL->gui->slotFocusOnMe(); emit closeEditor(editor, RevertModelCache); } } else if (event->type() == QEvent::ShortcutOverride) { const QKeyEvent *ke = dynamic_cast(event); if (ke->key() == Qt::Key_Escape || (ke->key() == Qt::Key_Backspace && ke->modifiers() == Qt::ControlModifier)) { event->accept(); return true; } } return false; } diff --git a/krusader/Panel/krcolorcache.cpp b/krusader/Panel/krcolorcache.cpp index 40f09232..3e1ee431 100644 --- a/krusader/Panel/krcolorcache.cpp +++ b/krusader/Panel/krcolorcache.cpp @@ -1,761 +1,763 @@ /***************************************************************************** * Copyright (C) 2000-2002 Shie Erlich * * Copyright (C) 2000-2002 Rafi Yanai * * Copyright (C) 2004-2020 Krusader Krew [https://krusader.org] * * * * This file is part of Krusader [https://krusader.org]. * * * * Krusader 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. * * * * Krusader 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 Krusader. If not, see [http://www.gnu.org/licenses/]. * *****************************************************************************/ #include "krcolorcache.h" #include "../krglobal.h" #include "../defaults.h" // QtCore #include #include #include // QtGui #include // QtWidgets #include #include // Macro: set target = col, if col is valid #define SETCOLOR(target, col) { if (col.isValid()) target = col; } // Static class, which lists all allowed keywords for a quick access. // Just call a method to initialize it. class KrColorSettingNames { static QMap s_colorNames; static QMap s_numNames; static QMap s_boolNames; static void initialize(); public: static QStringList getColorNames(); static bool isColorNameValid(const QString & settingName); static QStringList getNumNames(); static bool isNumNameValid(const QString & settingName); static QStringList getBoolNames(); static bool isBoolNameValid(const QString & settingName); } krColorSettingNames; QMap KrColorSettingNames::s_colorNames; QMap KrColorSettingNames::s_numNames; QMap KrColorSettingNames::s_boolNames; void KrColorSettingNames::initialize() { if (!s_colorNames.empty()) return; s_colorNames["Foreground"] = true; s_colorNames["Inactive Foreground"] = true; + s_colorNames["Rename Foreground"] = true; s_colorNames["Directory Foreground"] = true; s_colorNames["Inactive Directory Foreground"] = true; s_colorNames["Executable Foreground"] = true; s_colorNames["Inactive Executable Foreground"] = true; s_colorNames["Symlink Foreground"] = true; s_colorNames["Inactive Symlink Foreground"] = true; s_colorNames["Invalid Symlink Foreground"] = true; s_colorNames["Inactive Invalid Symlink Foreground"] = true; s_colorNames["Marked Foreground"] = true; s_colorNames["Inactive Marked Foreground"] = true; s_colorNames["Marked Background"] = true; s_colorNames["Inactive Marked Background"] = true; s_colorNames["Current Foreground"] = true; s_colorNames["Inactive Current Foreground"] = true; s_colorNames["Current Background"] = true; s_colorNames["Inactive Current Background"] = true; s_colorNames["Marked Current Foreground"] = true; s_colorNames["Inactive Marked Current Foreground"] = true; s_colorNames["Alternate Background"] = true; s_colorNames["Inactive Alternate Background"] = true; s_colorNames["Background"] = true; s_colorNames["Inactive Background"] = true; + s_colorNames["Rename Background"] = true; s_colorNames["Alternate Marked Background"] = true; s_colorNames["Inactive Alternate Marked Background"] = true; s_colorNames["Dim Target Color"] = true; s_numNames["Dim Factor"] = true; s_boolNames["KDE Default"] = true; s_boolNames["Enable Alternate Background"] = true; s_boolNames["Show Current Item Always"] = true; s_boolNames["Dim Inactive Colors"] = true; } QStringList KrColorSettingNames::getColorNames() { initialize(); return s_colorNames.keys(); } bool KrColorSettingNames::isColorNameValid(const QString & settingName) { initialize(); return s_colorNames.contains(settingName); } QStringList KrColorSettingNames::getNumNames() { initialize(); return s_numNames.keys(); } bool KrColorSettingNames::isNumNameValid(const QString & settingName) { initialize(); return s_numNames.contains(settingName); } QStringList KrColorSettingNames::getBoolNames() { initialize(); return s_boolNames.keys(); } bool KrColorSettingNames::isBoolNameValid(const QString & settingName) { initialize(); return s_boolNames.contains(settingName); } /* KrColorSettings implementation. Contains all properties in QMaps. loadFromConfig initializes them from krConfig. */ class KrColorSettingsImpl { friend class KrColorSettings; QMap m_colorTextValues; QMap m_colorValues; QMap m_numValues; QMap m_boolValues; void loadFromConfig(); }; void KrColorSettingsImpl::loadFromConfig() { KConfigGroup group(krConfig, "Colors"); QStringList names = KrColorSettingNames::getColorNames(); for (auto & name : names) { m_colorTextValues[name] = group.readEntry(name, QString()); if (m_colorTextValues[name].count(',') == 2) m_colorValues[name] = group.readEntry(name, QColor()); else m_colorValues[name] = QColor(); } names = KrColorSettingNames::getNumNames(); for (auto & name : names) { if (!group.readEntry(name, QString()).isEmpty()) { m_numValues[name] = group.readEntry(name, (long long)0); } } names = KrColorSettingNames::getBoolNames(); for (auto & name : names) { if (!group.readEntry(name, QString()).isEmpty()) { m_boolValues[name] = group.readEntry(name, false); } } } KrColorSettings::KrColorSettings() { m_impl = new KrColorSettingsImpl(); m_impl->loadFromConfig(); } KrColorSettings::KrColorSettings(const KrColorSettings & src) { m_impl = new KrColorSettingsImpl(); operator =(src); } KrColorSettings::~KrColorSettings() { delete m_impl; } const KrColorSettings & KrColorSettings::operator= (const KrColorSettings & src) { if (this == & src) return * this; QStringList names = KrColorSettingNames::getColorNames(); for (auto & name : names) { m_impl->m_colorTextValues[name] = src.m_impl->m_colorTextValues[name]; m_impl->m_colorValues[name] = src.m_impl->m_colorValues[name]; } for (QMap::Iterator it = src.m_impl->m_numValues.begin(); it != src.m_impl->m_numValues.end(); ++it) { m_impl->m_numValues[it.key()] = it.value(); } for (QMap::Iterator it = src.m_impl->m_boolValues.begin(); it != src.m_impl->m_boolValues.end(); ++it) { m_impl->m_boolValues[it.key()] = it.value(); } return * this; } QList KrColorSettings::getColorNames() { return KrColorSettingNames::getColorNames(); } bool KrColorSettings::isColorNameValid(const QString & settingName) { return KrColorSettingNames::isColorNameValid(settingName); } bool KrColorSettings::setColorValue(const QString & settingName, const QColor & color) { if (!isColorNameValid(settingName)) { qWarning() << "Invalid color setting name: " << settingName; return false; } m_impl->m_colorValues[settingName] = color; return true; } QColor KrColorSettings::getColorValue(const QString & settingName) const { if (!isColorNameValid(settingName)) { qWarning() << "Invalid color setting name: " << settingName; return QColor(); } return m_impl->m_colorValues[settingName]; } bool KrColorSettings::setColorTextValue(const QString & settingName, const QString & colorText) { if (!isColorNameValid(settingName)) { qWarning() << "Invalid color setting name: " << settingName; return false; } m_impl->m_colorTextValues[settingName] = colorText; return true; } QString KrColorSettings::getColorTextValue(const QString & settingName) const { if (!isColorNameValid(settingName)) { qWarning() << "Invalid color setting name: " << settingName; return QString(); } return m_impl->m_colorTextValues[settingName]; } QList KrColorSettings::getNumNames() { return KrColorSettingNames::getNumNames(); } bool KrColorSettings::isNumNameValid(const QString & settingName) { return KrColorSettingNames::isNumNameValid(settingName); } bool KrColorSettings::setNumValue(const QString & settingName, int value) { if (!isNumNameValid(settingName)) { qWarning() << "Invalid number setting name: " << settingName; return false; } m_impl->m_numValues[settingName] = value; return true; } int KrColorSettings::getNumValue(const QString & settingName, int defaultValue) const { if (!isNumNameValid(settingName)) { qWarning() << "Invalid number setting name: " << settingName; return 0; } if (!m_impl->m_numValues.contains(settingName)) return defaultValue; return m_impl->m_numValues[settingName]; } QList KrColorSettings::getBoolNames() { return KrColorSettingNames::getBoolNames(); } bool KrColorSettings::isBoolNameValid(const QString & settingName) { return KrColorSettingNames::isBoolNameValid(settingName); } bool KrColorSettings::setBoolValue(const QString & settingName, bool value) { if (!isBoolNameValid(settingName)) { qWarning() << "Invalid bool setting name: " << settingName; return false; } m_impl->m_boolValues[settingName] = value; return true; } int KrColorSettings::getBoolValue(const QString & settingName, bool defaultValue) const { if (!isBoolNameValid(settingName)) { qWarning() << "Invalid bool setting name: " << settingName; return false; } if (!m_impl->m_boolValues.contains(settingName)) return defaultValue; return m_impl->m_boolValues[settingName]; } KrColorItemType::KrColorItemType() { m_fileType = File; m_alternateBackgroundColor = false; m_activePanel = false; m_currentItem = false; m_selectedItem = false; } KrColorItemType::KrColorItemType(FileType type, bool alternateBackgroundColor, bool activePanel, bool currentItem, bool selectedItem) { m_fileType = type; m_alternateBackgroundColor = alternateBackgroundColor; m_activePanel = activePanel; m_currentItem = currentItem; m_selectedItem = selectedItem; } KrColorItemType::KrColorItemType(const KrColorItemType & src) { operator= (src); } const KrColorItemType & KrColorItemType::operator= (const KrColorItemType & src) { if (this == & src) return * this; m_fileType = src.m_fileType; m_alternateBackgroundColor = src.m_alternateBackgroundColor; m_activePanel = src.m_activePanel; m_currentItem = src.m_currentItem; m_selectedItem = src.m_selectedItem; return * this; } /* KrColorCache implementation. Contains the KrColorSettings used for teh calculation and the cache for the results. getColors is the only method to call. All other are taken from the previous versions. */ class KrColorCacheImpl { friend class KrColorCache; QMap m_cachedColors; KrColorSettings m_colorSettings; KrColorGroup getColors(const KrColorItemType & type) const; static const QColor & setColorIfContrastIsSufficient(const QColor & background, const QColor & color1, const QColor & color2); QColor getForegroundColor(bool isActive) const; QColor getSpecialForegroundColor(const QString & type, bool isActive) const; QColor getBackgroundColor(bool isActive) const; QColor getAlternateBackgroundColor(bool isActive) const; QColor getMarkedForegroundColor(bool isActive) const; QColor getMarkedBackgroundColor(bool isActive) const; QColor getAlternateMarkedBackgroundColor(bool isActive) const; QColor getCurrentForegroundColor(bool isActive) const; QColor getCurrentBackgroundColor(bool isActive) const; QColor getCurrentMarkedForegroundColor(bool isActive) const; QColor dimColor(QColor color, bool isBackgroundColor) const; }; KrColorGroup KrColorCacheImpl::getColors(const KrColorItemType & type) const { KrColorGroup result; if (m_colorSettings.getBoolValue("KDE Default", _KDEDefaultColors)) { bool enableAlternateBackground = m_colorSettings.getBoolValue("Enable Alternate Background", _AlternateBackground); QPalette p = QGuiApplication::palette(); QColor background = enableAlternateBackground && type.m_alternateBackgroundColor ? p.color(QPalette::Active, QPalette::Base) : p.color(QPalette::Active, QPalette::AlternateBase); result.setBackground(background); result.setText(p.color(QPalette::Active, QPalette::Text)); result.setHighlight(p.color(QPalette::Active, QPalette::Highlight)); result.setHighlightedText(p.color(QPalette::Active, QPalette::HighlightedText)); /* if (type.m_currentItem && type.m_activePanel) { QColor currentBackground = KColorScheme(QPalette::Active).background(KColorScheme::ActiveBackground).color(); // set the background result.setColor(QColorGroup::Highlight, currentBackground); result.setColor(QColorGroup::Base, currentBackground); result.setColor(QColorGroup::Background, currentBackground); }*/ return result; } bool markCurrentAlways = m_colorSettings.getBoolValue("Show Current Item Always", _ShowCurrentItemAlways); bool dimBackground = m_colorSettings.getBoolValue("Dim Inactive Colors", false); // cache m_activePanel flag. If color dimming is turned on, it is set to true, as the inactive colors // are calculated from the active ones at the end. bool isActive = type.m_activePanel; if (dimBackground) isActive = true; // First calculate fore- and background. QColor background = type.m_alternateBackgroundColor ? getAlternateBackgroundColor(isActive) : getBackgroundColor(isActive); QColor foreground; switch (type.m_fileType) { case KrColorItemType::Directory : foreground = getSpecialForegroundColor("Directory", isActive); break; case KrColorItemType::Executable : foreground = getSpecialForegroundColor("Executable", isActive); break; case KrColorItemType::InvalidSymlink : foreground = getSpecialForegroundColor("Invalid Symlink", isActive); break; case KrColorItemType::Symlink : foreground = getSpecialForegroundColor("Symlink", isActive); break; default: foreground = getForegroundColor(isActive); } // set the background color result.setBackground(background); // set the foreground color result.setText(foreground); // now the color of a marked item QColor markedBackground = type.m_alternateBackgroundColor ? getAlternateMarkedBackgroundColor(isActive) : getMarkedBackgroundColor(isActive); QColor markedForeground = getMarkedForegroundColor(isActive); if (!markedForeground.isValid()) // transparent // choose fore- or background, depending on its contrast compared to markedBackground markedForeground = setColorIfContrastIsSufficient(markedBackground, foreground, background); // set it in the color group (different group color than normal foreground!) result.setHighlightedText(markedForeground); result.setHighlight(markedBackground); // In case the current item is a selected one, set the fore- and background colors for the contrast calculation below if (type.m_selectedItem) { background = markedBackground; foreground = markedForeground; } // finally the current item if (type.m_currentItem && (markCurrentAlways || isActive)) { // if this is the current item AND the panels has the focus OR the current should be marked always QColor currentBackground = getCurrentBackgroundColor(isActive); if (!currentBackground.isValid()) // transparent currentBackground = background; // set the background result.setHighlight(currentBackground); result.setBackground(currentBackground); QColor color; if (type.m_selectedItem) color = getCurrentMarkedForegroundColor(isActive); if (!color.isValid()) { // not used color = getCurrentForegroundColor(isActive); if (!color.isValid()) // transparent // choose fore- or background, depending on its contrast compared to markedBackground color = setColorIfContrastIsSufficient(currentBackground, foreground, background); } // set the foreground result.setText(color); result.setHighlightedText(color); } if (dimBackground && !type.m_activePanel) { // if color dimming is chosen, dim the colors for the inactive panel result.setBackground(dimColor(result.background(), true)); result.setText(dimColor(result.text(), false)); result.setHighlightedText(dimColor(result.highlightedText(), false)); result.setHighlight(dimColor(result.highlight(), true)); } return result; } const QColor & KrColorCacheImpl::setColorIfContrastIsSufficient(const QColor & background, const QColor & color1, const QColor & color2) { #define sqr(x) ((x)*(x)) int contrast = sqr(color1.red() - background.red()) + sqr(color1.green() - background.green()) + sqr(color1.blue() - background.blue()); // if the contrast between background and color1 is too small, take color2 instead. if (contrast < 1000) return color2; return color1; } QColor KrColorCacheImpl::getForegroundColor(bool isActive) const { QPalette p = QGuiApplication::palette(); QColor color = p.color(QPalette::Active, QPalette::Text); SETCOLOR(color, m_colorSettings.getColorValue("Foreground")); if (!isActive) SETCOLOR(color, m_colorSettings.getColorValue("Inactive Foreground")); return color; } QColor KrColorCacheImpl::getSpecialForegroundColor(const QString & type, bool isActive) const { QString colorName = "Inactive " + type + " Foreground"; if (!isActive && m_colorSettings.getColorTextValue(colorName) == "Inactive Foreground") return getForegroundColor(false); QColor color = m_colorSettings.getColorValue(type + " Foreground"); if (!isActive) SETCOLOR(color, m_colorSettings.getColorValue(colorName)); if (!color.isValid()) return getForegroundColor(isActive); return color; } QColor KrColorCacheImpl::getBackgroundColor(bool isActive) const { QColor color = QGuiApplication::palette().color(QPalette::Active, QPalette::Base); SETCOLOR(color, m_colorSettings.getColorValue("Background")); if (!isActive) SETCOLOR(color, m_colorSettings.getColorValue("Inactive Background")); return color; } QColor KrColorCacheImpl::getAlternateBackgroundColor(bool isActive) const { QPalette p = QGuiApplication::palette(); if (isActive && m_colorSettings.getColorTextValue("Alternate Background") == "Background") return getBackgroundColor(true); if (!isActive && m_colorSettings.getColorTextValue("Inactive Alternate Background").isEmpty()) return getAlternateBackgroundColor(true); if (!isActive && m_colorSettings.getColorTextValue("Inactive Alternate Background") == "Inactive Background") return getBackgroundColor(false); QColor color = isActive ? m_colorSettings.getColorValue("Alternate Background") : m_colorSettings.getColorValue("Inactive Alternate Background"); if (!color.isValid()) color = p.color(QPalette::Active, QPalette::AlternateBase); if (!color.isValid()) color = p.color(QPalette::Active, QPalette::Base); return color; } QColor KrColorCacheImpl::getMarkedForegroundColor(bool isActive) const { QString colorName = isActive ? "Marked Foreground" : "Inactive Marked Foreground"; if (m_colorSettings.getColorTextValue(colorName) == "transparent") return QColor(); if (isActive && m_colorSettings.getColorTextValue(colorName).isEmpty()) return QGuiApplication::palette().color(QPalette::Active, QPalette::HighlightedText); if (!isActive && m_colorSettings.getColorTextValue(colorName).isEmpty()) return getMarkedForegroundColor(true); return m_colorSettings.getColorValue(colorName); } QColor KrColorCacheImpl::getMarkedBackgroundColor(bool isActive) const { if (isActive && m_colorSettings.getColorTextValue("Marked Background").isEmpty()) return QGuiApplication::palette().color(QPalette::Active, QPalette::Highlight); if (isActive && m_colorSettings.getColorTextValue("Marked Background") == "Background") return getBackgroundColor(true); if (!isActive && m_colorSettings.getColorTextValue("Inactive Marked Background").isEmpty()) return getMarkedBackgroundColor(true); if (!isActive && m_colorSettings.getColorTextValue("Inactive Marked Background") == "Inactive Background") return getBackgroundColor(false); return isActive ? m_colorSettings.getColorValue("Marked Background") : m_colorSettings.getColorValue("Inactive Marked Background"); } QColor KrColorCacheImpl::getAlternateMarkedBackgroundColor(bool isActive) const { if (isActive && m_colorSettings.getColorTextValue("Alternate Marked Background") == "Alternate Background") return getAlternateBackgroundColor(true); if (isActive && m_colorSettings.getColorTextValue("Alternate Marked Background").isEmpty()) return getMarkedBackgroundColor(true); if (!isActive && m_colorSettings.getColorTextValue("Inactive Alternate Marked Background").isEmpty()) return getAlternateMarkedBackgroundColor(true); if (!isActive && m_colorSettings.getColorTextValue("Inactive Alternate Marked Background") == "Inactive Alternate Background") return getAlternateBackgroundColor(false); if (!isActive && m_colorSettings.getColorTextValue("Inactive Alternate Marked Background") == "Inactive Marked Background") return getMarkedBackgroundColor(false); return isActive ? m_colorSettings.getColorValue("Alternate Marked Background") : m_colorSettings.getColorValue("Inactive Alternate Marked Background"); } QColor KrColorCacheImpl::getCurrentForegroundColor(bool isActive) const { QColor color = m_colorSettings.getColorValue("Current Foreground"); if (!isActive) SETCOLOR(color, m_colorSettings.getColorValue("Inactive Current Foreground")); return color; } QColor KrColorCacheImpl::getCurrentBackgroundColor(bool isActive) const { if (isActive && m_colorSettings.getColorTextValue("Current Background").isEmpty()) return QColor(); if (isActive && m_colorSettings.getColorTextValue("Current Background") == "Background") return getBackgroundColor(true); if (!isActive && m_colorSettings.getColorTextValue("Inactive Current Background").isEmpty()) return getCurrentBackgroundColor(true); if (!isActive && m_colorSettings.getColorTextValue("Inactive Current Background") == "Inactive Background") return getBackgroundColor(false); return isActive ? m_colorSettings.getColorValue("Current Background") : m_colorSettings.getColorValue("Inactive Current Background"); } QColor KrColorCacheImpl::getCurrentMarkedForegroundColor(bool isActive) const { QString colorName = isActive ? "Marked Current Foreground" : "Inactive Marked Current Foreground"; if (isActive && m_colorSettings.getColorTextValue(colorName).isEmpty()) return QColor(); if (isActive && m_colorSettings.getColorTextValue(colorName) == "Marked Foreground") return getMarkedForegroundColor(true); if (!isActive && m_colorSettings.getColorTextValue(colorName).isEmpty()) return getCurrentMarkedForegroundColor(true); if (!isActive && m_colorSettings.getColorTextValue(colorName) == "Inactive Marked Foreground") return getMarkedForegroundColor(false); return m_colorSettings.getColorValue(colorName); } QColor KrColorCacheImpl::dimColor(QColor color, bool /* isBackgroundColor */) const { int dimFactor = m_colorSettings.getNumValue("Dim Factor", 100); QColor targetColor = m_colorSettings.getColorValue("Dim Target Color"); if (!targetColor.isValid()) targetColor = QColor(255, 255, 255); bool dimBackground = m_colorSettings.getBoolValue("Dim Inactive Colors", false); bool dim = dimFactor >= 0 && dimFactor < 100 && dimBackground; if (dim) color = KrColorCache::dimColor(color, dimFactor, targetColor); return color; } KrColorCache * KrColorCache::m_instance = nullptr; KrColorCache::KrColorCache() { m_impl = new KrColorCacheImpl; } KrColorCache::~KrColorCache() { delete m_impl; } KrColorCache & KrColorCache::getColorCache() { if (!m_instance) { m_instance = new KrColorCache; m_instance->refreshColors(); } return * m_instance; } void KrColorCache::getColors(KrColorGroup & result, const KrColorItemType & type) const { // for the cache lookup: calculate a unique key from the type char hashKey[128]; switch (type.m_fileType) { case KrColorItemType::Directory : strcpy(hashKey, "Directory"); break; case KrColorItemType::Executable : strcpy(hashKey, "Executable"); break; case KrColorItemType::InvalidSymlink : strcpy(hashKey, "InvalidSymlink"); break; case KrColorItemType::Symlink : strcpy(hashKey, "Symlink"); break; default: strcpy(hashKey, "File"); } if (type.m_activePanel) strcat(hashKey, "-Active"); if (type.m_alternateBackgroundColor) strcat(hashKey, "-Alternate"); if (type.m_currentItem) strcat(hashKey, "-Current"); if (type.m_selectedItem) strcat(hashKey, "-Selected"); // lookup in cache if (!m_impl->m_cachedColors.contains(hashKey)) // not found: calculate color group and store it in cache m_impl->m_cachedColors[hashKey] = m_impl->getColors(type); // get color group from cache const KrColorGroup & col = m_impl->m_cachedColors[hashKey]; // copy colors in question to result color group result.setBackground(col.background()); result.setText(col.text()); result.setHighlightedText(col.highlightedText()); result.setHighlight(col.highlight()); } bool KrColorCache::getDimSettings(QColor & dimColor, int & dimFactor) { if (m_impl->m_colorSettings.getBoolValue("Dim Inactive Colors", false)) { dimFactor = m_impl->m_colorSettings.getNumValue("Dim Factor", 100); dimColor = m_impl->m_colorSettings.getColorValue("Dim Target Color"); if (!dimColor.isValid()) dimColor.setRgb(255, 255, 255); return dimFactor >= 0 && dimFactor < 100; } return false; } QColor KrColorCache::dimColor(const QColor & color, int dim, const QColor & targetColor) { return QColor((targetColor.red() * (100 - dim) + color.red() * dim) / 100, (targetColor.green() * (100 - dim) + color.green() * dim) / 100, (targetColor.blue() * (100 - dim) + color.blue() * dim) / 100); } void KrColorCache::refreshColors() { m_impl->m_cachedColors.clear(); m_impl->m_colorSettings = KrColorSettings(); QPixmapCache::clear(); // dimmed icons are cached colorsRefreshed(); } void KrColorCache::setColors(const KrColorSettings & colorSettings) { m_impl->m_cachedColors.clear(); m_impl->m_colorSettings = colorSettings; QPixmapCache::clear(); // dimmed icons are cached colorsRefreshed(); }