Browse Source

VWebView: add css_color_mapping in palette file for copying HTMl

If the mapping is specified, we will replace the foreground color with
the mapping when the content is copied.
Le Tan 8 years ago
parent
commit
324d7cd444

+ 2 - 0
src/dialog/vcopytextashtmldialog.cpp

@@ -65,6 +65,8 @@ void VCopyTextAsHtmlDialog::setConvertedHtml(const QUrl &p_baseUrl,
     m_htmlViewer->setHtml(html, p_baseUrl);
     setHtmlVisible(true);
 
+    VWebUtils::translateColors(html);
+
     // Fix image source.
     if (g_config->getFixImageSrcInWebWhenCopied()) {
         VWebUtils::fixImageSrcInHtml(p_baseUrl, html);

+ 6 - 0
src/resources/themes/v_moonlight/v_moonlight.palette

@@ -7,6 +7,12 @@ mdhl_file=v_moonlight.mdhl
 css_file=v_moonlight.css
 codeblock_css_file=v_moonlight_codeblock.css
 
+; This mapping will be used to translate colors when the content of HTML is copied
+; without background. You could just specify the foreground colors mapping here.
+; It is useful for dark mode theme. '#aabbcc' or 'red' formats are supported.
+; col1:col1_new,col2:col2_new
+css_color_mapping=#abb2bf:#363636,#282c34:#f5f5f5,#61afef:#0099ff,#98c379:#8e24aa,#2c313a:#e0e0e0,#5c6370:#666666,#373e47:#999999,#6c6c6c:#444444,#c678dd:#0000ee,#e06c75:#880000,#56b6c2:#af00d7,#e6c07b:#008700,#d19a66:#bc6060,#61aeee:#bc6060
+
 [phony]
 ; Abstract color attributes.
 master_fg=@edit_fg

+ 68 - 0
src/utils/vwebutils.cpp

@@ -4,6 +4,10 @@
 #include <QFileInfo>
 #include <QDebug>
 
+#include "vpalette.h"
+
+extern VPalette *g_palette;
+
 VWebUtils::VWebUtils()
 {
 }
@@ -56,3 +60,67 @@ bool VWebUtils::fixImageSrcInHtml(const QUrl &p_baseUrl, QString &p_html)
 
     return changed;
 }
+
+bool VWebUtils::removeBackgroundColor(QString &p_html)
+{
+    QRegExp reg("(<[^>]+\\sstyle=[^>]*(\\s|\"))background(-color)?:[^;]+;([^>]*>)");
+    int size = p_html.size();
+    p_html.replace(reg, "\\1\\4");
+    return p_html.size() != size;
+}
+
+bool VWebUtils::translateColors(QString &p_html)
+{
+    bool changed = false;
+
+    const QHash<QString, QString> &mapping = g_palette->getColorMapping();
+    if (mapping.isEmpty()) {
+        return changed;
+    }
+
+    QRegExp tagReg("(<[^>]+\\sstyle=[^>]*>)");
+    // Won't mixed up with background-color.
+    QRegExp colorReg("(\\s|\")color:([^;]+);");
+
+    int pos = 0;
+    while (pos < p_html.size()) {
+        int idx = p_html.indexOf(tagReg, pos);
+        if (idx == -1) {
+            break;
+        }
+
+        QString styleStr = tagReg.cap(1);
+        QString alteredStyleStr = styleStr;
+
+        int posb = 0;
+        while (posb < alteredStyleStr.size()) {
+            int idxb = alteredStyleStr.indexOf(colorReg, posb);
+            if (idxb == -1) {
+                break;
+            }
+
+            QString col = colorReg.cap(2).trimmed().toLower();
+            auto it = mapping.find(col);
+            if (it == mapping.end()) {
+                posb = idxb + colorReg.matchedLength();
+                continue;
+            }
+
+            // Replace the color.
+            QString newCol = it.value();
+            // Add one extra space between color and :.
+            QString newStr = QString("%1color : %2;").arg(colorReg.cap(1)).arg(newCol);
+            alteredStyleStr.replace(idxb, colorReg.matchedLength(), newStr);
+            posb = idxb + newStr.size();
+            changed = true;
+        }
+
+        pos = idx + tagReg.matchedLength();
+        if (changed) {
+            pos = pos + alteredStyleStr.size() - styleStr.size();
+            p_html.replace(idx, tagReg.matchedLength(), alteredStyleStr);
+        }
+    }
+
+    return changed;
+}

+ 6 - 0
src/utils/vwebutils.h

@@ -11,6 +11,12 @@ public:
     // Fix <img src> in @p_html.
     static bool fixImageSrcInHtml(const QUrl &p_baseUrl, QString &p_html);
 
+    // Remove background color style in @p_html.
+    static bool removeBackgroundColor(QString &p_html);
+
+    // Translate color styles in @p_html using mappings from VPalette.
+    static bool translateColors(QString &p_html);
+
 private:
     VWebUtils();
 };

+ 27 - 0
src/vpalette.cpp

@@ -180,6 +180,19 @@ QMap<QString, QString> VPalette::codeBlockCssStylesFromThemes(const QList<QStrin
     return styles;
 }
 
+static QString translateColorValue(const QString &p_col)
+{
+    QString tmp = p_col.trimmed().toLower();
+    if (tmp.startsWith('#')) {
+        QColor col(tmp);
+        int r, g, b;
+        col.getRgb(&r, &g, &b);
+        return QString("rgb(%1, %2, %3)").arg(r).arg(g).arg(b);
+    } else {
+        return tmp;
+    }
+}
+
 VPaletteMetaData VPalette::getPaletteMetaData(const QString &p_paletteFile)
 {
     VPaletteMetaData data;
@@ -208,6 +221,20 @@ VPaletteMetaData VPalette::getPaletteMetaData(const QString &p_paletteFile)
         data.m_codeBlockCssFile = dir.filePath(val);
     }
 
+    QStringList mapping = settings.value("css_color_mapping").toStringList();
+    if (!mapping.isEmpty()) {
+        for (auto const & m : mapping) {
+            QStringList vals = m.split(':');
+            if (vals.size() != 2) {
+                continue;
+            }
+
+            // Translate the #aabbcc into rgb(aa, bb, cc) format.
+            data.m_colorMapping.insert(translateColorValue(vals[0]),
+                                       translateColorValue(vals[1]));
+        }
+    }
+
     settings.endGroup();
 
     return data;

+ 14 - 2
src/vpalette.h

@@ -15,13 +15,18 @@ struct VPaletteMetaData
     QString m_cssFile;
     QString m_codeBlockCssFile;
 
+    // Color mapping when copied.
+    // All lower-case.
+    QHash<QString, QString> m_colorMapping;
+
     QString toString() const
     {
-        return QString("palette metadata qss=%1 mdhl=%2 css=%3 codeBlockCss=%4")
+        return QString("palette metadata qss=%1 mdhl=%2 css=%3 codeBlockCss=%4 colorMappingSize=%5")
                       .arg(m_qssFile)
                       .arg(m_mdhlFile)
                       .arg(m_cssFile)
-                      .arg(m_codeBlockCssFile);
+                      .arg(m_codeBlockCssFile)
+                      .arg(m_colorMapping.size());
     }
 };
 
@@ -39,6 +44,8 @@ public:
     // Fill "@xxx" in @p_text with corresponding style.
     void fillStyle(QString &p_text) const;
 
+    const QHash<QString, QString> &getColorMapping() const;
+
     // Read themes and return the mappings of editor styles.
     static QMap<QString, QString> editorStylesFromThemes(const QList<QString> &p_themeFiles);
 
@@ -77,4 +84,9 @@ private:
     VPaletteMetaData m_data;
 };
 
+inline const QHash<QString, QString> &VPalette::getColorMapping() const
+{
+    return m_data.m_colorMapping;
+}
+
 #endif // VPALETTE_H

+ 8 - 10
src/vwebview.cpp

@@ -229,14 +229,6 @@ void VWebView::hideUnusedActions(QMenu *p_menu)
     }
 }
 
-static bool removeBackgroundColor(QString &p_html)
-{
-    QRegExp reg("(<[^>]+\\sstyle=[^>]*(\\s|\"))background(-color)?:[^;]+;([^>]*>)");
-    int size = p_html.size();
-    p_html.replace(reg, "\\1\\4");
-    return p_html.size() != size;
-}
-
 bool VWebView::removeStyles(QString &p_html)
 {
     bool changed = false;
@@ -336,8 +328,14 @@ void VWebView::alterHtmlMimeData(QClipboard *p_clipboard,
     }
 
     // Remove background color.
-    if (p_removeBackground && removeBackgroundColor(html)) {
-        altered = true;
+    if (p_removeBackground) {
+        if (VWebUtils::removeBackgroundColor(html)) {
+            altered = true;
+        }
+
+        if (VWebUtils::translateColors(html)) {
+            altered = true;
+        }
     }
 
     // Fix local relative images.