File indexing completed on 2024-04-28 17:06:20
0001 /* 0002 SPDX-FileCopyrightText: 2000-2002 Shie Erlich <erlich@users.sourceforge.net> 0003 SPDX-FileCopyrightText: 2000-2002 Rafi Yanai <yanai@users.sourceforge.net> 0004 SPDX-FileCopyrightText: 2004-2022 Krusader Krew <https://krusader.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "krcolorcache.h" 0010 #include "../defaults.h" 0011 #include "../krglobal.h" 0012 0013 // QtCore 0014 #include <QDebug> 0015 #include <QFile> 0016 #include <QList> 0017 // QtGui 0018 #include <QPixmapCache> 0019 // QtWidgets 0020 #include <QApplication> 0021 0022 #include <KConfigCore/KSharedConfig> 0023 0024 // Macro: set target = col, if col is valid 0025 #define SETCOLOR(target, col) \ 0026 { \ 0027 if (col.isValid()) \ 0028 target = col; \ 0029 } 0030 0031 // Static class, which lists all allowed keywords for a quick access. 0032 // Just call a method to initialize it. 0033 class KrColorSettingNames 0034 { 0035 static QMap<QString, bool> s_colorNames; 0036 static QMap<QString, bool> s_numNames; 0037 static QMap<QString, bool> s_boolNames; 0038 static void initialize(); 0039 0040 public: 0041 static QStringList getColorNames(); 0042 static bool isColorNameValid(const QString &settingName); 0043 static QStringList getNumNames(); 0044 static bool isNumNameValid(const QString &settingName); 0045 static QStringList getBoolNames(); 0046 static bool isBoolNameValid(const QString &settingName); 0047 } krColorSettingNames; 0048 0049 QMap<QString, bool> KrColorSettingNames::s_colorNames; 0050 QMap<QString, bool> KrColorSettingNames::s_numNames; 0051 QMap<QString, bool> KrColorSettingNames::s_boolNames; 0052 0053 void KrColorSettingNames::initialize() 0054 { 0055 if (!s_colorNames.empty()) 0056 return; 0057 s_colorNames["Foreground"] = true; 0058 s_colorNames["Inactive Foreground"] = true; 0059 s_colorNames["Rename Foreground"] = true; 0060 s_colorNames["Directory Foreground"] = true; 0061 s_colorNames["Inactive Directory Foreground"] = true; 0062 s_colorNames["Executable Foreground"] = true; 0063 s_colorNames["Inactive Executable Foreground"] = true; 0064 s_colorNames["Symlink Foreground"] = true; 0065 s_colorNames["Inactive Symlink Foreground"] = true; 0066 s_colorNames["Invalid Symlink Foreground"] = true; 0067 s_colorNames["Inactive Invalid Symlink Foreground"] = true; 0068 s_colorNames["Marked Foreground"] = true; 0069 s_colorNames["Inactive Marked Foreground"] = true; 0070 s_colorNames["Marked Background"] = true; 0071 s_colorNames["Inactive Marked Background"] = true; 0072 s_colorNames["Current Foreground"] = true; 0073 s_colorNames["Inactive Current Foreground"] = true; 0074 s_colorNames["Current Background"] = true; 0075 s_colorNames["Inactive Current Background"] = true; 0076 s_colorNames["Marked Current Foreground"] = true; 0077 s_colorNames["Inactive Marked Current Foreground"] = true; 0078 s_colorNames["Alternate Background"] = true; 0079 s_colorNames["Inactive Alternate Background"] = true; 0080 s_colorNames["Background"] = true; 0081 s_colorNames["Inactive Background"] = true; 0082 s_colorNames["Rename Background"] = true; 0083 s_colorNames["Alternate Marked Background"] = true; 0084 s_colorNames["Inactive Alternate Marked Background"] = true; 0085 s_colorNames["Dim Target Color"] = true; 0086 0087 s_numNames["Dim Factor"] = true; 0088 0089 s_boolNames["KDE Default"] = true; 0090 s_boolNames["Enable Alternate Background"] = true; 0091 s_boolNames["Show Current Item Always"] = true; 0092 s_boolNames["Dim Inactive Colors"] = true; 0093 } 0094 0095 QStringList KrColorSettingNames::getColorNames() 0096 { 0097 initialize(); 0098 return s_colorNames.keys(); 0099 } 0100 0101 bool KrColorSettingNames::isColorNameValid(const QString &settingName) 0102 { 0103 initialize(); 0104 return s_colorNames.contains(settingName); 0105 } 0106 0107 QStringList KrColorSettingNames::getNumNames() 0108 { 0109 initialize(); 0110 return s_numNames.keys(); 0111 } 0112 0113 bool KrColorSettingNames::isNumNameValid(const QString &settingName) 0114 { 0115 initialize(); 0116 return s_numNames.contains(settingName); 0117 } 0118 0119 QStringList KrColorSettingNames::getBoolNames() 0120 { 0121 initialize(); 0122 return s_boolNames.keys(); 0123 } 0124 0125 bool KrColorSettingNames::isBoolNameValid(const QString &settingName) 0126 { 0127 initialize(); 0128 return s_boolNames.contains(settingName); 0129 } 0130 0131 /* 0132 KrColorSettings implementation. Contains all properties in QMaps. loadFromConfig initializes them from krConfig. 0133 */ 0134 class KrColorSettingsImpl 0135 { 0136 friend class KrColorSettings; 0137 QMap<QString, QString> m_colorTextValues; 0138 QMap<QString, QColor> m_colorValues; 0139 QMap<QString, int> m_numValues; 0140 QMap<QString, bool> m_boolValues; 0141 void loadFromConfig(); 0142 }; 0143 0144 void KrColorSettingsImpl::loadFromConfig() 0145 { 0146 KConfigGroup group(krConfig, "Colors"); 0147 QStringList names = KrColorSettingNames::getColorNames(); 0148 for (auto &name : names) { 0149 m_colorTextValues[name] = group.readEntry(name, QString()); 0150 if (m_colorTextValues[name].count(',') == 2) 0151 m_colorValues[name] = group.readEntry(name, QColor()); 0152 else 0153 m_colorValues[name] = QColor(); 0154 } 0155 names = KrColorSettingNames::getNumNames(); 0156 for (auto &name : names) { 0157 if (!group.readEntry(name, QString()).isEmpty()) { 0158 m_numValues[name] = group.readEntry(name, 0); 0159 } 0160 } 0161 names = KrColorSettingNames::getBoolNames(); 0162 for (auto &name : names) { 0163 if (!group.readEntry(name, QString()).isEmpty()) { 0164 m_boolValues[name] = group.readEntry(name, false); 0165 } 0166 } 0167 } 0168 0169 KrColorSettings::KrColorSettings() 0170 { 0171 m_impl = new KrColorSettingsImpl(); 0172 m_impl->loadFromConfig(); 0173 } 0174 0175 KrColorSettings::KrColorSettings(const KrColorSettings &src) 0176 { 0177 m_impl = new KrColorSettingsImpl(); 0178 operator=(src); 0179 } 0180 0181 KrColorSettings::~KrColorSettings() 0182 { 0183 delete m_impl; 0184 } 0185 0186 const KrColorSettings &KrColorSettings::operator=(const KrColorSettings &src) 0187 { 0188 if (this == &src) 0189 return *this; 0190 QStringList names = KrColorSettingNames::getColorNames(); 0191 for (auto &name : names) { 0192 m_impl->m_colorTextValues[name] = src.m_impl->m_colorTextValues[name]; 0193 m_impl->m_colorValues[name] = src.m_impl->m_colorValues[name]; 0194 } 0195 for (QMap<QString, int>::Iterator it = src.m_impl->m_numValues.begin(); it != src.m_impl->m_numValues.end(); ++it) { 0196 m_impl->m_numValues[it.key()] = it.value(); 0197 } 0198 for (QMap<QString, bool>::Iterator it = src.m_impl->m_boolValues.begin(); it != src.m_impl->m_boolValues.end(); ++it) { 0199 m_impl->m_boolValues[it.key()] = it.value(); 0200 } 0201 return *this; 0202 } 0203 0204 QList<QString> KrColorSettings::getColorNames() 0205 { 0206 return KrColorSettingNames::getColorNames(); 0207 } 0208 0209 bool KrColorSettings::isColorNameValid(const QString &settingName) 0210 { 0211 return KrColorSettingNames::isColorNameValid(settingName); 0212 } 0213 0214 bool KrColorSettings::setColorValue(const QString &settingName, const QColor &color) 0215 { 0216 if (!isColorNameValid(settingName)) { 0217 qWarning() << "Invalid color setting name: " << settingName; 0218 return false; 0219 } 0220 m_impl->m_colorValues[settingName] = color; 0221 return true; 0222 } 0223 0224 QColor KrColorSettings::getColorValue(const QString &settingName) const 0225 { 0226 if (!isColorNameValid(settingName)) { 0227 qWarning() << "Invalid color setting name: " << settingName; 0228 return QColor(); 0229 } 0230 return m_impl->m_colorValues[settingName]; 0231 } 0232 0233 bool KrColorSettings::setColorTextValue(const QString &settingName, const QString &colorText) 0234 { 0235 if (!isColorNameValid(settingName)) { 0236 qWarning() << "Invalid color setting name: " << settingName; 0237 return false; 0238 } 0239 m_impl->m_colorTextValues[settingName] = colorText; 0240 return true; 0241 } 0242 0243 QString KrColorSettings::getColorTextValue(const QString &settingName) const 0244 { 0245 if (!isColorNameValid(settingName)) { 0246 qWarning() << "Invalid color setting name: " << settingName; 0247 return QString(); 0248 } 0249 return m_impl->m_colorTextValues[settingName]; 0250 } 0251 0252 QList<QString> KrColorSettings::getNumNames() 0253 { 0254 return KrColorSettingNames::getNumNames(); 0255 } 0256 0257 bool KrColorSettings::isNumNameValid(const QString &settingName) 0258 { 0259 return KrColorSettingNames::isNumNameValid(settingName); 0260 } 0261 0262 bool KrColorSettings::setNumValue(const QString &settingName, int value) 0263 { 0264 if (!isNumNameValid(settingName)) { 0265 qWarning() << "Invalid number setting name: " << settingName; 0266 return false; 0267 } 0268 m_impl->m_numValues[settingName] = value; 0269 return true; 0270 } 0271 0272 int KrColorSettings::getNumValue(const QString &settingName, int defaultValue) const 0273 { 0274 if (!isNumNameValid(settingName)) { 0275 qWarning() << "Invalid number setting name: " << settingName; 0276 return 0; 0277 } 0278 if (!m_impl->m_numValues.contains(settingName)) 0279 return defaultValue; 0280 return m_impl->m_numValues[settingName]; 0281 } 0282 0283 QList<QString> KrColorSettings::getBoolNames() 0284 { 0285 return KrColorSettingNames::getBoolNames(); 0286 } 0287 0288 bool KrColorSettings::isBoolNameValid(const QString &settingName) 0289 { 0290 return KrColorSettingNames::isBoolNameValid(settingName); 0291 } 0292 0293 bool KrColorSettings::setBoolValue(const QString &settingName, bool value) 0294 { 0295 if (!isBoolNameValid(settingName)) { 0296 qWarning() << "Invalid bool setting name: " << settingName; 0297 return false; 0298 } 0299 m_impl->m_boolValues[settingName] = value; 0300 return true; 0301 } 0302 0303 int KrColorSettings::getBoolValue(const QString &settingName, bool defaultValue) const 0304 { 0305 if (!isBoolNameValid(settingName)) { 0306 qWarning() << "Invalid bool setting name: " << settingName; 0307 return false; 0308 } 0309 if (!m_impl->m_boolValues.contains(settingName)) 0310 return defaultValue; 0311 return m_impl->m_boolValues[settingName]; 0312 } 0313 0314 KrColorItemType::KrColorItemType() 0315 { 0316 m_fileType = File; 0317 m_alternateBackgroundColor = false; 0318 m_activePanel = false; 0319 m_currentItem = false; 0320 m_selectedItem = false; 0321 } 0322 0323 KrColorItemType::KrColorItemType(FileType type, bool alternateBackgroundColor, bool activePanel, bool currentItem, bool selectedItem) 0324 { 0325 m_fileType = type; 0326 m_alternateBackgroundColor = alternateBackgroundColor; 0327 m_activePanel = activePanel; 0328 m_currentItem = currentItem; 0329 m_selectedItem = selectedItem; 0330 } 0331 0332 KrColorItemType::KrColorItemType(const KrColorItemType &src) 0333 { 0334 operator=(src); 0335 } 0336 0337 const KrColorItemType &KrColorItemType::operator=(const KrColorItemType &src) 0338 { 0339 if (this == &src) 0340 return *this; 0341 m_fileType = src.m_fileType; 0342 m_alternateBackgroundColor = src.m_alternateBackgroundColor; 0343 m_activePanel = src.m_activePanel; 0344 m_currentItem = src.m_currentItem; 0345 m_selectedItem = src.m_selectedItem; 0346 return *this; 0347 } 0348 0349 /* 0350 KrColorCache implementation. Contains the KrColorSettings used for teh calculation and the cache for the results. 0351 getColors is the only method to call. All other are taken from the previous versions. 0352 */ 0353 class KrColorCacheImpl 0354 { 0355 friend class KrColorCache; 0356 QMap<QString, KrColorGroup> m_cachedColors; 0357 KrColorSettings m_colorSettings; 0358 0359 KrColorGroup getColors(const KrColorItemType &type) const; 0360 static const QColor &setColorIfContrastIsSufficient(const QColor &background, const QColor &color1, const QColor &color2); 0361 QColor getForegroundColor(bool isActive) const; 0362 QColor getSpecialForegroundColor(const QString &type, bool isActive) const; 0363 QColor getBackgroundColor(bool isActive) const; 0364 QColor getAlternateBackgroundColor(bool isActive) const; 0365 QColor getMarkedForegroundColor(bool isActive) const; 0366 QColor getMarkedBackgroundColor(bool isActive) const; 0367 QColor getAlternateMarkedBackgroundColor(bool isActive) const; 0368 QColor getCurrentForegroundColor(bool isActive) const; 0369 QColor getCurrentBackgroundColor(bool isActive) const; 0370 QColor getCurrentMarkedForegroundColor(bool isActive) const; 0371 QColor dimColor(QColor color, bool isBackgroundColor) const; 0372 }; 0373 0374 KrColorGroup KrColorCacheImpl::getColors(const KrColorItemType &type) const 0375 { 0376 KrColorGroup result; 0377 if (m_colorSettings.getBoolValue("KDE Default", _KDEDefaultColors)) { 0378 bool enableAlternateBackground = m_colorSettings.getBoolValue("Enable Alternate Background", _AlternateBackground); 0379 0380 QPalette p = QGuiApplication::palette(); 0381 QColor background = enableAlternateBackground && type.m_alternateBackgroundColor ? p.color(QPalette::Active, QPalette::Base) 0382 : p.color(QPalette::Active, QPalette::AlternateBase); 0383 result.setBackground(background); 0384 result.setText(p.color(QPalette::Active, QPalette::Text)); 0385 result.setHighlight(p.color(QPalette::Active, QPalette::Highlight)); 0386 result.setHighlightedText(p.color(QPalette::Active, QPalette::HighlightedText)); 0387 0388 /* if (type.m_currentItem && type.m_activePanel) 0389 { 0390 QColor currentBackground = KColorScheme(QPalette::Active).background(KColorScheme::ActiveBackground).color(); 0391 // set the background 0392 result.setColor(QColorGroup::Highlight, currentBackground); 0393 result.setColor(QColorGroup::Base, currentBackground); 0394 result.setColor(QColorGroup::Background, currentBackground); 0395 }*/ 0396 return result; 0397 } 0398 bool markCurrentAlways = m_colorSettings.getBoolValue("Show Current Item Always", _ShowCurrentItemAlways); 0399 bool dimBackground = m_colorSettings.getBoolValue("Dim Inactive Colors", false); 0400 0401 // cache m_activePanel flag. If color dimming is turned on, it is set to true, as the inactive colors 0402 // are calculated from the active ones at the end. 0403 bool isActive = type.m_activePanel; 0404 if (dimBackground) 0405 isActive = true; 0406 0407 // First calculate fore- and background. 0408 QColor background = type.m_alternateBackgroundColor ? getAlternateBackgroundColor(isActive) : getBackgroundColor(isActive); 0409 QColor foreground; 0410 switch (type.m_fileType) { 0411 case KrColorItemType::Directory: 0412 foreground = getSpecialForegroundColor("Directory", isActive); 0413 break; 0414 case KrColorItemType::Executable: 0415 foreground = getSpecialForegroundColor("Executable", isActive); 0416 break; 0417 case KrColorItemType::InvalidSymlink: 0418 foreground = getSpecialForegroundColor("Invalid Symlink", isActive); 0419 break; 0420 case KrColorItemType::Symlink: 0421 foreground = getSpecialForegroundColor("Symlink", isActive); 0422 break; 0423 default: 0424 foreground = getForegroundColor(isActive); 0425 } 0426 0427 // set the background color 0428 result.setBackground(background); 0429 0430 // set the foreground color 0431 result.setText(foreground); 0432 0433 // now the color of a marked item 0434 QColor markedBackground = type.m_alternateBackgroundColor ? getAlternateMarkedBackgroundColor(isActive) : getMarkedBackgroundColor(isActive); 0435 QColor markedForeground = getMarkedForegroundColor(isActive); 0436 if (!markedForeground.isValid()) // transparent 0437 // choose fore- or background, depending on its contrast compared to markedBackground 0438 markedForeground = setColorIfContrastIsSufficient(markedBackground, foreground, background); 0439 0440 // set it in the color group (different group color than normal foreground!) 0441 result.setHighlightedText(markedForeground); 0442 result.setHighlight(markedBackground); 0443 0444 // In case the current item is a selected one, set the fore- and background colors for the contrast calculation below 0445 if (type.m_selectedItem) { 0446 background = markedBackground; 0447 foreground = markedForeground; 0448 } 0449 0450 // finally the current item 0451 if (type.m_currentItem && (markCurrentAlways || isActive)) { 0452 // if this is the current item AND the panels has the focus OR the current should be marked always 0453 QColor currentBackground = getCurrentBackgroundColor(isActive); 0454 0455 if (!currentBackground.isValid()) // transparent 0456 currentBackground = background; 0457 0458 // set the background 0459 result.setHighlight(currentBackground); 0460 result.setBackground(currentBackground); 0461 0462 QColor color; 0463 if (type.m_selectedItem) 0464 color = getCurrentMarkedForegroundColor(isActive); 0465 if (!color.isValid()) { // not used 0466 color = getCurrentForegroundColor(isActive); 0467 if (!color.isValid()) // transparent 0468 // choose fore- or background, depending on its contrast compared to markedBackground 0469 color = setColorIfContrastIsSufficient(currentBackground, foreground, background); 0470 } 0471 0472 // set the foreground 0473 result.setText(color); 0474 result.setHighlightedText(color); 0475 } 0476 0477 if (dimBackground && !type.m_activePanel) { 0478 // if color dimming is chosen, dim the colors for the inactive panel 0479 result.setBackground(dimColor(result.background(), true)); 0480 result.setText(dimColor(result.text(), false)); 0481 result.setHighlightedText(dimColor(result.highlightedText(), false)); 0482 result.setHighlight(dimColor(result.highlight(), true)); 0483 } 0484 return result; 0485 } 0486 0487 const QColor &KrColorCacheImpl::setColorIfContrastIsSufficient(const QColor &background, const QColor &color1, const QColor &color2) 0488 { 0489 #define sqr(x) ((x) * (x)) 0490 int contrast = sqr(color1.red() - background.red()) + sqr(color1.green() - background.green()) + sqr(color1.blue() - background.blue()); 0491 0492 // if the contrast between background and color1 is too small, take color2 instead. 0493 if (contrast < 1000) 0494 return color2; 0495 return color1; 0496 } 0497 0498 QColor KrColorCacheImpl::getForegroundColor(bool isActive) const 0499 { 0500 QPalette p = QGuiApplication::palette(); 0501 QColor color = p.color(QPalette::Active, QPalette::Text); 0502 SETCOLOR(color, m_colorSettings.getColorValue("Foreground")); 0503 if (!isActive) 0504 SETCOLOR(color, m_colorSettings.getColorValue("Inactive Foreground")); 0505 return color; 0506 } 0507 0508 QColor KrColorCacheImpl::getSpecialForegroundColor(const QString &type, bool isActive) const 0509 { 0510 QString colorName = "Inactive " + type + " Foreground"; 0511 if (!isActive && m_colorSettings.getColorTextValue(colorName) == "Inactive Foreground") 0512 return getForegroundColor(false); 0513 QColor color = m_colorSettings.getColorValue(type + " Foreground"); 0514 if (!isActive) 0515 SETCOLOR(color, m_colorSettings.getColorValue(colorName)); 0516 if (!color.isValid()) 0517 return getForegroundColor(isActive); 0518 return color; 0519 } 0520 0521 QColor KrColorCacheImpl::getBackgroundColor(bool isActive) const 0522 { 0523 QColor color = QGuiApplication::palette().color(QPalette::Active, QPalette::Base); 0524 SETCOLOR(color, m_colorSettings.getColorValue("Background")); 0525 if (!isActive) 0526 SETCOLOR(color, m_colorSettings.getColorValue("Inactive Background")); 0527 return color; 0528 } 0529 0530 QColor KrColorCacheImpl::getAlternateBackgroundColor(bool isActive) const 0531 { 0532 QPalette p = QGuiApplication::palette(); 0533 if (isActive && m_colorSettings.getColorTextValue("Alternate Background") == "Background") 0534 return getBackgroundColor(true); 0535 if (!isActive && m_colorSettings.getColorTextValue("Inactive Alternate Background").isEmpty()) 0536 return getAlternateBackgroundColor(true); 0537 if (!isActive && m_colorSettings.getColorTextValue("Inactive Alternate Background") == "Inactive Background") 0538 return getBackgroundColor(false); 0539 QColor color = isActive ? m_colorSettings.getColorValue("Alternate Background") : m_colorSettings.getColorValue("Inactive Alternate Background"); 0540 if (!color.isValid()) 0541 color = p.color(QPalette::Active, QPalette::AlternateBase); 0542 if (!color.isValid()) 0543 color = p.color(QPalette::Active, QPalette::Base); 0544 return color; 0545 } 0546 0547 QColor KrColorCacheImpl::getMarkedForegroundColor(bool isActive) const 0548 { 0549 QString colorName = isActive ? "Marked Foreground" : "Inactive Marked Foreground"; 0550 if (m_colorSettings.getColorTextValue(colorName) == "transparent") 0551 return QColor(); 0552 if (isActive && m_colorSettings.getColorTextValue(colorName).isEmpty()) 0553 return QGuiApplication::palette().color(QPalette::Active, QPalette::HighlightedText); 0554 if (!isActive && m_colorSettings.getColorTextValue(colorName).isEmpty()) 0555 return getMarkedForegroundColor(true); 0556 return m_colorSettings.getColorValue(colorName); 0557 } 0558 0559 QColor KrColorCacheImpl::getMarkedBackgroundColor(bool isActive) const 0560 { 0561 if (isActive && m_colorSettings.getColorTextValue("Marked Background").isEmpty()) 0562 return QGuiApplication::palette().color(QPalette::Active, QPalette::Highlight); 0563 if (isActive && m_colorSettings.getColorTextValue("Marked Background") == "Background") 0564 return getBackgroundColor(true); 0565 if (!isActive && m_colorSettings.getColorTextValue("Inactive Marked Background").isEmpty()) 0566 return getMarkedBackgroundColor(true); 0567 if (!isActive && m_colorSettings.getColorTextValue("Inactive Marked Background") == "Inactive Background") 0568 return getBackgroundColor(false); 0569 return isActive ? m_colorSettings.getColorValue("Marked Background") : m_colorSettings.getColorValue("Inactive Marked Background"); 0570 } 0571 0572 QColor KrColorCacheImpl::getAlternateMarkedBackgroundColor(bool isActive) const 0573 { 0574 if (isActive && m_colorSettings.getColorTextValue("Alternate Marked Background") == "Alternate Background") 0575 return getAlternateBackgroundColor(true); 0576 if (isActive && m_colorSettings.getColorTextValue("Alternate Marked Background").isEmpty()) 0577 return getMarkedBackgroundColor(true); 0578 if (!isActive && m_colorSettings.getColorTextValue("Inactive Alternate Marked Background").isEmpty()) 0579 return getAlternateMarkedBackgroundColor(true); 0580 if (!isActive && m_colorSettings.getColorTextValue("Inactive Alternate Marked Background") == "Inactive Alternate Background") 0581 return getAlternateBackgroundColor(false); 0582 if (!isActive && m_colorSettings.getColorTextValue("Inactive Alternate Marked Background") == "Inactive Marked Background") 0583 return getMarkedBackgroundColor(false); 0584 return isActive ? m_colorSettings.getColorValue("Alternate Marked Background") : m_colorSettings.getColorValue("Inactive Alternate Marked Background"); 0585 } 0586 0587 QColor KrColorCacheImpl::getCurrentForegroundColor(bool isActive) const 0588 { 0589 QColor color = m_colorSettings.getColorValue("Current Foreground"); 0590 if (!isActive) 0591 SETCOLOR(color, m_colorSettings.getColorValue("Inactive Current Foreground")); 0592 return color; 0593 } 0594 0595 QColor KrColorCacheImpl::getCurrentBackgroundColor(bool isActive) const 0596 { 0597 if (isActive && m_colorSettings.getColorTextValue("Current Background").isEmpty()) 0598 return QColor(); 0599 if (isActive && m_colorSettings.getColorTextValue("Current Background") == "Background") 0600 return getBackgroundColor(true); 0601 if (!isActive && m_colorSettings.getColorTextValue("Inactive Current Background").isEmpty()) 0602 return getCurrentBackgroundColor(true); 0603 if (!isActive && m_colorSettings.getColorTextValue("Inactive Current Background") == "Inactive Background") 0604 return getBackgroundColor(false); 0605 return isActive ? m_colorSettings.getColorValue("Current Background") : m_colorSettings.getColorValue("Inactive Current Background"); 0606 } 0607 0608 QColor KrColorCacheImpl::getCurrentMarkedForegroundColor(bool isActive) const 0609 { 0610 QString colorName = isActive ? "Marked Current Foreground" : "Inactive Marked Current Foreground"; 0611 if (isActive && m_colorSettings.getColorTextValue(colorName).isEmpty()) 0612 return QColor(); 0613 if (isActive && m_colorSettings.getColorTextValue(colorName) == "Marked Foreground") 0614 return getMarkedForegroundColor(true); 0615 if (!isActive && m_colorSettings.getColorTextValue(colorName).isEmpty()) 0616 return getCurrentMarkedForegroundColor(true); 0617 if (!isActive && m_colorSettings.getColorTextValue(colorName) == "Inactive Marked Foreground") 0618 return getMarkedForegroundColor(false); 0619 return m_colorSettings.getColorValue(colorName); 0620 } 0621 0622 QColor KrColorCacheImpl::dimColor(QColor color, bool /* isBackgroundColor */) const 0623 { 0624 int dimFactor = m_colorSettings.getNumValue("Dim Factor", 100); 0625 QColor targetColor = m_colorSettings.getColorValue("Dim Target Color"); 0626 if (!targetColor.isValid()) 0627 targetColor = QColor(255, 255, 255); 0628 bool dimBackground = m_colorSettings.getBoolValue("Dim Inactive Colors", false); 0629 bool dim = dimFactor >= 0 && dimFactor < 100 && dimBackground; 0630 if (dim) 0631 color = KrColorCache::dimColor(color, dimFactor, targetColor); 0632 return color; 0633 } 0634 0635 KrColorCache *KrColorCache::m_instance = nullptr; 0636 0637 KrColorCache::KrColorCache() 0638 { 0639 m_impl = new KrColorCacheImpl; 0640 } 0641 0642 KrColorCache::~KrColorCache() 0643 { 0644 delete m_impl; 0645 } 0646 0647 KrColorCache &KrColorCache::getColorCache() 0648 { 0649 if (!m_instance) { 0650 m_instance = new KrColorCache; 0651 m_instance->refreshColors(); 0652 } 0653 return *m_instance; 0654 } 0655 0656 void KrColorCache::getColors(KrColorGroup &result, const KrColorItemType &type) const 0657 { 0658 // for the cache lookup: calculate a unique key from the type 0659 char hashKey[128]; 0660 switch (type.m_fileType) { 0661 case KrColorItemType::Directory: 0662 strcpy(hashKey, "Directory"); 0663 break; 0664 case KrColorItemType::Executable: 0665 strcpy(hashKey, "Executable"); 0666 break; 0667 case KrColorItemType::InvalidSymlink: 0668 strcpy(hashKey, "InvalidSymlink"); 0669 break; 0670 case KrColorItemType::Symlink: 0671 strcpy(hashKey, "Symlink"); 0672 break; 0673 default: 0674 strcpy(hashKey, "File"); 0675 } 0676 if (type.m_activePanel) 0677 strcat(hashKey, "-Active"); 0678 if (type.m_alternateBackgroundColor) 0679 strcat(hashKey, "-Alternate"); 0680 if (type.m_currentItem) 0681 strcat(hashKey, "-Current"); 0682 if (type.m_selectedItem) 0683 strcat(hashKey, "-Selected"); 0684 0685 // lookup in cache 0686 if (!m_impl->m_cachedColors.contains(hashKey)) 0687 // not found: calculate color group and store it in cache 0688 m_impl->m_cachedColors[hashKey] = m_impl->getColors(type); 0689 0690 // get color group from cache 0691 const KrColorGroup &col = m_impl->m_cachedColors[hashKey]; 0692 0693 // copy colors in question to result color group 0694 result.setBackground(col.background()); 0695 result.setText(col.text()); 0696 result.setHighlightedText(col.highlightedText()); 0697 result.setHighlight(col.highlight()); 0698 } 0699 0700 bool KrColorCache::getDimSettings(QColor &dimColor, int &dimFactor) 0701 { 0702 if (m_impl->m_colorSettings.getBoolValue("Dim Inactive Colors", false)) { 0703 dimFactor = m_impl->m_colorSettings.getNumValue("Dim Factor", 100); 0704 dimColor = m_impl->m_colorSettings.getColorValue("Dim Target Color"); 0705 if (!dimColor.isValid()) 0706 dimColor.setRgb(255, 255, 255); 0707 return dimFactor >= 0 && dimFactor < 100; 0708 } 0709 return false; 0710 } 0711 0712 QColor KrColorCache::dimColor(const QColor &color, int dim, const QColor &targetColor) 0713 { 0714 return QColor((targetColor.red() * (100 - dim) + color.red() * dim) / 100, 0715 (targetColor.green() * (100 - dim) + color.green() * dim) / 100, 0716 (targetColor.blue() * (100 - dim) + color.blue() * dim) / 100); 0717 } 0718 0719 void KrColorCache::refreshColors() 0720 { 0721 m_impl->m_cachedColors.clear(); 0722 m_impl->m_colorSettings = KrColorSettings(); 0723 QPixmapCache::clear(); // dimmed icons are cached 0724 emit colorsRefreshed(); 0725 } 0726 0727 void KrColorCache::setColors(const KrColorSettings &colorSettings) 0728 { 0729 m_impl->m_cachedColors.clear(); 0730 m_impl->m_colorSettings = colorSettings; 0731 QPixmapCache::clear(); // dimmed icons are cached 0732 emit colorsRefreshed(); 0733 }