5#include "RabbitCommonDir.h"
8#include <QStyleFactory>
11#include <QApplication>
12#include <QRegularExpression>
13#include <QLoggingCategory>
23static Q_LOGGING_CATEGORY(log,
"RabbitCommon.Style")
25CStyle::CStyle(QObject *parent) : QObject(parent)
26 , m_bModifyStyleSheetFile(false)
27 , m_bModifyStyleName(false)
29 qDebug(log) << Q_FUNC_INFO;
31 m_szDefaultIconTheme = QIcon::themeName();
32 if(m_szDefaultIconTheme.isEmpty()) {
33 m_szDefaultIconTheme =
"rabbit-black";
34 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
35 const auto scheme = QGuiApplication::styleHints()->colorScheme();
36 if(Qt::ColorScheme::Dark == scheme)
37 m_szDefaultIconTheme =
"rabbit-white";
39 QIcon::setThemeName(m_szDefaultIconTheme);
41#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) && !defined(Q_OS_WINDOWS)
42 if(!QIcon::fallbackThemeName().isEmpty())
43 qDebug(log) <<
"Old icon fallback theme:" << QIcon::fallbackThemeName();
45 m_szDefaultFallbackIconTheme =
"rabbit-black";
46 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
47 const auto scheme = QGuiApplication::styleHints()->colorScheme();
48 if(Qt::ColorScheme::Dark == scheme)
49 m_szDefaultFallbackIconTheme =
"rabbit-white";
51 QIcon::setFallbackThemeName(m_szDefaultFallbackIconTheme);
54 <<
"Icon theme name:" << QIcon::themeName() <<
"\n"
55 <<
"Icon theme search paths:" << QIcon::themeSearchPaths() <<
"\n"
56 #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
57 <<
"Fallback theme name:" << QIcon::fallbackThemeName() <<
"\n"
59 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
60 <<
"Fallback search paths:" << QIcon::fallbackSearchPaths() <<
"\n"
65#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
66 if(QApplication::instance()) {
67 check = connect(QApplication::styleHints(),
68 SIGNAL(colorSchemeChanged(Qt::ColorScheme)),
69 this, SLOT(slotColorSchemeChanged(Qt::ColorScheme)));
75 if(QStyleFactory::keys().contains(
"Fusion"))
76 m_szStyleName =
"Fusion";
78 #if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)
79 if(QApplication::style())
80 m_szStyleName = QApplication::style()->name();
82 if(!QStyleFactory::keys().isEmpty())
83 m_szStyleName = QStyleFactory::keys().at(0);
86 if(m_szStyleName.isEmpty()) {
87 if(!QStyleFactory::keys().isEmpty())
88 m_szStyleName = QStyleFactory::keys().at(0);
90 qDebug(log) <<
"Init style name:" << m_szStyleName;
96 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
97 QSettings::IniFormat);
98 QIcon::setThemeSearchPaths(
99 QIcon::themeSearchPaths()
100 << RabbitCommon::CDir::Instance()->GetDirIcons(
true));
101 bool bIconTheme = set.value(
"Style/Icon/Theme/Enable",
true).toBool();
103 QString szThemeName = QIcon::themeName();
104 if(szThemeName.isEmpty())
105 szThemeName = m_szDefaultIconTheme;
106 szThemeName = set.value(
"Style/Icon/Theme", szThemeName).toString();
108#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
109 Qt::ColorScheme scheme = Qt::ColorScheme::Unknown;
110 if(QGuiApplication::styleHints())
111 scheme = QGuiApplication::styleHints()->colorScheme();
113 static QRegularExpression reBlack(
"black|[Dd]ark");
114 QRegularExpressionMatch matchBlack = reBlack.match(szThemeName);
115 if (Qt::ColorScheme::Dark == scheme && matchBlack.hasMatch()) {
116 QString szInfo = tr(
"Current system theme is dark, current theme is ") + QString(
"\"") + szThemeName +
"\". ";
117 szInfo += tr(
"it's almost impossible to find the icon because its color matches the current system theme.");
118 szThemeName =
"rabbit-white";
119 szInfo +=
" " + tr(
"change to ") + szThemeName;
120 qInfo(log) << szInfo;
122 static QRegularExpression reWhite(
"[Ww]hite|[L|l]ight");
123 QRegularExpressionMatch matchWhite = reWhite.match(szThemeName);
124 if (Qt::ColorScheme::Light == scheme && matchWhite.hasMatch()) {
125 QString szInfo = tr(
"Current system theme is light, current theme is ") + QString(
"\"") + szThemeName +
"\". ";
126 szInfo += tr(
"it's almost impossible to find the icon because its color matches the current system theme.");
127 szThemeName =
"rabbit-black";
128 szInfo +=
" " + tr(
"change to ") + szThemeName;
129 qInfo(log) << szInfo;
133 QIcon::setThemeName(szThemeName);
135#if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0) && !defined(Q_OS_WINDOWS)
136 QIcon::setFallbackSearchPaths(
137 QIcon::fallbackSearchPaths()
138 << RabbitCommon::CDir::Instance()->GetDirIcons(
true));
139 QString szFallbackThemeName = QIcon::fallbackThemeName();
140 if(szFallbackThemeName.isEmpty())
141 szFallbackThemeName = m_szDefaultFallbackIconTheme;
142 QIcon::setFallbackThemeName(set.value(
"Style/Icon/Theme/Fallback",
143 szFallbackThemeName).toString());
145 #if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
146 if (Qt::ColorScheme::Dark == scheme && matchBlack.hasMatch()) {
147 QString szInfo = tr(
"Current system theme is dark, current theme is ") + QString(
"\"") + szFallbackThemeName +
"\". ";
148 szInfo += tr(
"it's almost impossible to find the icon because its color matches the current system theme.");
149 szFallbackThemeName =
"rabbit-white";
150 szInfo +=
" " + tr(
"change to ") + szFallbackThemeName;
151 qInfo(log) << szInfo;
153 if (Qt::ColorScheme::Light == scheme && matchWhite.hasMatch()) {
154 QString szInfo = tr(
"Current system theme is light, current theme is ") + QString(
"\"") + szFallbackThemeName +
"\". ";
155 szInfo += tr(
"it's almost impossible to find the icon because its color matches the current system theme.");
156 szFallbackThemeName =
"rabbit-black";
157 szInfo +=
" " + tr(
"change to ") + szFallbackThemeName;
158 qInfo(log) << szInfo;
163 qDebug(log) << Q_FUNC_INFO <<
"\n"
164 <<
"Icon theme name:" << QIcon::themeName() <<
"\n"
165 <<
"Icon theme search paths:" << QIcon::themeSearchPaths() <<
"\n"
166 #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
167 <<
"Fallback theme name:" << QIcon::fallbackThemeName() <<
"\n"
169 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
170 <<
"Fallback search paths:" << QIcon::fallbackSearchPaths() <<
"\n"
177 QString szName = set.value(
"Style/Name", GetStyleName()).toString();
178 SetStyleName(szName);
182 QString szFile = set.value(
"Style/Sheet/File", GetStyleSheetFile()).toString();
183 SetStyleSheetFile(szFile);
194int CStyle::ReLoadStyle()
196 if(m_bModifyStyleName) {
198 m_bModifyStyleName =
false;
200 if(m_bModifyStyleSheetFile) {
202 m_bModifyStyleSheetFile =
false;
214#if QT_VERSION >= QT_VERSION_CHECK(6, 1, 0)
215 if(QApplication::style() && QApplication::style()->name() == szName)
218 qInfo(log) <<
"Apply style:" << szName;
219 QApplication::setStyle(QStyleFactory::create(szName));
232 if(QStyleFactory::keys().contains(
"Fusion")) {
234 QApplication::setStyle(QStyleFactory::create(
"Fusion"));
247 qApp->setStyleSheet(
"");
251 if(file.open(QFile::ReadOnly))
253 qInfo(log) <<
"Load style file:" << szFile;
254 QString stylesheet= file.readAll();
255 QString pattern(
"QPalette\\{background:#[0-9a-fA-F]+;\\}");
256#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
257 QRegularExpression re(pattern);
258 QRegularExpressionMatch match = re.match(stylesheet);
259 if (match.hasMatch()) {
260 QString matched = match.captured(0);
261 if(!matched.isEmpty())
263 QRegularExpression rePalette(
"#[0-9a-fA-F]+");
264 match = rePalette.match(matched);
267 QString paletteColor = match.captured(0);
268 qApp->setPalette(QPalette(QColor(paletteColor)));
274 int pos = rx.indexIn(stylesheet);
277 QString szPalette = rx.cap();
278 QRegExp rxPalette(
"#[0-9a-fA-F]+");
279 int pos = rxPalette.indexIn(stylesheet);
282 QString paletteColor = rxPalette.cap();
283 qApp->setPalette(QPalette(QColor(paletteColor)));
287 qApp->setStyleSheet(stylesheet);
292 qCritical(log) <<
"file open file fail:" << szFile;
300 QString szFile = m_szStyleSheetFile;
301 QString szPath = RabbitCommon::CDir::Instance()->
GetDirData(
true)
307 szPath =
"/usr/share/style";
309 if(!szFile.isEmpty()) {
310 QFileInfo fi(szFile);
311 szPath = fi.absoluteFilePath();
313 qDebug(log) <<
"Path:" << szPath;
314 QWidget* pParent =
dynamic_cast<QWidget*
>(this->parent());
315 szFile = QFileDialog::getOpenFileName(pParent, tr(
"Open style"),
317 tr(
"Style files(*.qss *.css);; All files(*.*)"));
321QString CStyle::GetStyleSheetFile()
323 if(!m_szStyleSheetFile.isEmpty())
324 if(!QFile::exists(m_szStyleSheetFile))
326 return m_szStyleSheetFile;
329void CStyle::SetStyleSheetFile(
const QString &file)
331 if(m_szStyleSheetFile == file)
333 m_szStyleSheetFile = file;
334 m_bModifyStyleSheetFile =
true;
335 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
336 QSettings::IniFormat);
337 set.setValue(
"Style/Sheet/File", m_szStyleSheetFile);
340QString CStyle::GetStyleName()
342 return m_szStyleName;
345void CStyle::SetStyleName(
const QString &szName)
347 if(szName == m_szStyleName)
349 m_szStyleName = szName;
350 m_bModifyStyleName =
true;
351 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
352 QSettings::IniFormat);
353 set.setValue(
"Style/Name", m_szStyleName);
356#if QT_VERSION >= QT_VERSION_CHECK(6, 5, 0)
357void CStyle::slotColorSchemeChanged(Qt::ColorScheme colorScheme)
360 QString szColorScheme;
361 QRegularExpression reBlack(
"[Bb]lack|[Dd]ark");
362 QRegularExpressionMatch match = reBlack.match(QIcon::themeName());
363 if (Qt::ColorScheme::Dark == colorScheme && match.hasMatch()) {
365 szThemeName =
"rabbit-white";
366 szColorScheme = tr(
"Dark");
368 QRegularExpression reWhite(
"[Ww]hite|[L|l]ight");
369 match = reWhite.match(QIcon::themeName());
370 if (Qt::ColorScheme::Light == colorScheme && match.hasMatch()) {
372 szThemeName =
"rabbit-black";
373 szColorScheme = tr(
"Light");
375 if(szThemeName.isEmpty())
return;
376 QString szInfo = tr(
"Current system theme is") +
" \"" + szColorScheme +
"\", " + tr(
"current theme is") + QString(
" \"") + QIcon::themeName() +
"\". ";
377 szInfo += tr(
"it's almost impossible to find the icon because its color matches the current system theme.");
378 szInfo +=
" " + tr(
"change to ") +
"\"" + szThemeName +
"\"?";
379 auto ret = QMessageBox::information(
nullptr, tr(
"Change theme"), szInfo,
380 QMessageBox::Ok | QMessageBox::No,
382 if(QMessageBox::Ok == ret) {
383 QSettings set(RabbitCommon::CDir::Instance()->GetFileUserConfigure(),
384 QSettings::IniFormat);
385 QIcon::setThemeName(szThemeName);
386 szThemeName = set.value(
"Style/Icon/Theme", szThemeName).toString();
QString GetDirData(bool bReadOnly=false)
Get data directory.
int LoadStyle()
Load style from configure file.
int LoadStyleSheet(const QString &szFile)
Load style sheet from the file.
QString GetStyleSheet()
Open get style sheet dialog.