vpalette.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "vpalette.h"
  2. #include <QSettings>
  3. #include <QRegExp>
  4. #include <QFileInfo>
  5. #include <QDir>
  6. #include <QDebug>
  7. #include "utils/vutils.h"
  8. VPalette::VPalette(const QString &p_file)
  9. {
  10. init(p_file);
  11. }
  12. void VPalette::init(const QString &p_file)
  13. {
  14. m_file = QFileInfo(p_file).absoluteFilePath();
  15. QSettings settings(p_file, QSettings::IniFormat);
  16. m_data = getPaletteMetaData(m_file);
  17. initPaleteFromSettings(&settings, "phony");
  18. initPaleteFromSettings(&settings, "soft_defined");
  19. initPaleteFromSettings(&settings, "widgets");
  20. qDebug() << "theme file" << m_file << m_data.toString();
  21. }
  22. void VPalette::initPaleteFromSettings(QSettings *p_settings, const QString &p_group)
  23. {
  24. QRegExp reg("@(\\w+)");
  25. p_settings->beginGroup(p_group);
  26. // Used to store undefined pairs.
  27. QHash<QString, QString> undefined;
  28. QStringList keys = p_settings->childKeys();
  29. for (auto const & key : keys) {
  30. if (key.isEmpty()) {
  31. continue;
  32. }
  33. QString val = p_settings->value(key).toString();
  34. if (reg.exactMatch(val)) {
  35. auto it = m_palette.find(reg.cap(1));
  36. if (it != m_palette.end()) {
  37. val = it.value();
  38. } else {
  39. undefined.insert(key, reg.cap(1));
  40. continue;
  41. }
  42. }
  43. m_palette.insert(key, val);
  44. }
  45. // Handle definition: a=@b b=@c c=red.
  46. int iter = 0;
  47. while (!undefined.isEmpty()) {
  48. if (iter >= undefined.size()) {
  49. qWarning() << "cyclic palette definitions found" << undefined;
  50. break;
  51. }
  52. for (auto it = undefined.begin(); it != undefined.end();) {
  53. auto pit = m_palette.find(it.value());
  54. if (pit != m_palette.end()) {
  55. m_palette.insert(it.key(), pit.value());
  56. iter = 0;
  57. it = undefined.erase(it);
  58. } else {
  59. ++iter;
  60. ++it;
  61. }
  62. }
  63. }
  64. p_settings->endGroup();
  65. }
  66. QString VPalette::color(const QString &p_name) const
  67. {
  68. auto it = m_palette.find(p_name);
  69. if (it != m_palette.end()) {
  70. return it.value();
  71. }
  72. return QString();
  73. }
  74. void VPalette::fillStyle(QString &p_text) const
  75. {
  76. // Cap(2) is the string to be replaced.
  77. QRegExp reg("(\\s|:)@(\\w+)(?=\\W)");
  78. int pos = 0;
  79. while (pos < p_text.size()) {
  80. int idx = p_text.indexOf(reg, pos);
  81. if (idx == -1) {
  82. break;
  83. }
  84. QString name = reg.cap(2);
  85. QString val = color(name);
  86. if (val.isEmpty()) {
  87. pos = idx + reg.matchedLength();
  88. } else {
  89. pos = idx + reg.matchedLength() + val.size() - name.size() - 1;
  90. p_text.replace(idx + reg.cap(1).size(), name.size() + 1, val);
  91. }
  92. }
  93. }
  94. QString VPalette::fetchQtStyleSheet() const
  95. {
  96. QString style = VUtils::readFileFromDisk(m_data.m_qssFile);
  97. fillStyle(style);
  98. fillAbsoluteUrl(style);
  99. return style;
  100. }
  101. void VPalette::fillAbsoluteUrl(QString &p_style) const
  102. {
  103. // Cap(2) is the string to be replaced.
  104. QRegExp reg("(\\s|:)url\\(([^\\(\\)]+)\\)(?=\\W)");
  105. int literalSize = QString("url(").size();
  106. QDir dir(VUtils::basePathFromPath(m_file));
  107. int pos = 0;
  108. while (pos < p_style.size()) {
  109. int idx = p_style.indexOf(reg, pos);
  110. if (idx == -1) {
  111. break;
  112. }
  113. QString url = reg.cap(2);
  114. QString abUrl = dir.filePath(url);
  115. pos = idx + reg.matchedLength() + abUrl.size() - url.size();
  116. p_style.replace(idx + reg.cap(1).size() + literalSize, url.size(), abUrl);
  117. }
  118. }
  119. QMap<QString, QString> VPalette::editorStylesFromThemes(const QList<QString> &p_themeFiles)
  120. {
  121. QMap<QString, QString> styles;
  122. for (auto const & theme : p_themeFiles) {
  123. QString value = getPaletteMetaData(theme).m_mdhlFile;
  124. if (!value.isEmpty()) {
  125. styles.insert(themeName(theme) + "/" + QFileInfo(value).completeBaseName(), value);
  126. }
  127. }
  128. return styles;
  129. }
  130. QMap<QString, QString> VPalette::cssStylesFromThemes(const QList<QString> &p_themeFiles)
  131. {
  132. QMap<QString, QString> styles;
  133. for (auto const & theme : p_themeFiles) {
  134. QString value = getPaletteMetaData(theme).m_cssFile;
  135. if (!value.isEmpty()) {
  136. styles.insert(themeName(theme) + "/" + QFileInfo(value).completeBaseName(), value);
  137. }
  138. }
  139. return styles;
  140. }
  141. QMap<QString, QString> VPalette::codeBlockCssStylesFromThemes(const QList<QString> &p_themeFiles)
  142. {
  143. QMap<QString, QString> styles;
  144. for (auto const & theme : p_themeFiles) {
  145. QString value = getPaletteMetaData(theme).m_codeBlockCssFile;
  146. if (!value.isEmpty()) {
  147. styles.insert(themeName(theme) + "/" + QFileInfo(value).completeBaseName(), value);
  148. }
  149. }
  150. return styles;
  151. }
  152. VPaletteMetaData VPalette::getPaletteMetaData(const QString &p_paletteFile)
  153. {
  154. VPaletteMetaData data;
  155. QSettings settings(p_paletteFile, QSettings::IniFormat);
  156. QDir dir(VUtils::basePathFromPath(QFileInfo(p_paletteFile).absoluteFilePath()));
  157. settings.beginGroup("metadata");
  158. QString val = settings.value("qss_file").toString();
  159. if (!val.isEmpty()) {
  160. data.m_qssFile = dir.filePath(val);
  161. }
  162. val = settings.value("mdhl_file").toString();
  163. if (!val.isEmpty()) {
  164. data.m_mdhlFile = dir.filePath(val);
  165. }
  166. val = settings.value("css_file").toString();
  167. if (!val.isEmpty()) {
  168. data.m_cssFile = dir.filePath(val);
  169. }
  170. val = settings.value("codeblock_css_file").toString();
  171. if (!val.isEmpty()) {
  172. data.m_codeBlockCssFile = dir.filePath(val);
  173. }
  174. settings.endGroup();
  175. return data;
  176. }
  177. QString VPalette::themeName(const QString &p_paletteFile)
  178. {
  179. return QFileInfo(p_paletteFile).completeBaseName();
  180. }
  181. QString VPalette::themeEditorStyle(const QString &p_paletteFile)
  182. {
  183. VPaletteMetaData data = getPaletteMetaData(p_paletteFile);
  184. return themeName(p_paletteFile) + "/" + QFileInfo(data.m_mdhlFile).completeBaseName();
  185. }
  186. QString VPalette::themeCssStyle(const QString &p_paletteFile)
  187. {
  188. VPaletteMetaData data = getPaletteMetaData(p_paletteFile);
  189. return themeName(p_paletteFile) + "/" + QFileInfo(data.m_cssFile).completeBaseName();
  190. }
  191. QString VPalette::themeCodeBlockCssStyle(const QString &p_paletteFile)
  192. {
  193. VPaletteMetaData data = getPaletteMetaData(p_paletteFile);
  194. return themeName(p_paletteFile) + "/" + QFileInfo(data.m_codeBlockCssFile).completeBaseName();
  195. }