mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
support custom CSS styles
VNote will find CSS files in the "styles" folder under the config folder.
This commit is contained in:
parent
c642d60757
commit
d0d4e1443d
@ -1,6 +1,6 @@
|
||||
[global]
|
||||
welcome_page_path=:/resources/welcome.html
|
||||
template_css_url=qrc:/resources/markdown.css
|
||||
template_css=default
|
||||
current_notebook=0
|
||||
tab_stop_width=4
|
||||
is_expand_tab=true
|
||||
|
@ -10,11 +10,13 @@
|
||||
#include "utils/vutils.h"
|
||||
#include "vstyleparser.h"
|
||||
|
||||
const QString VConfigManager::orgName = QString("tamlok");
|
||||
const QString VConfigManager::orgName = QString("vnote");
|
||||
const QString VConfigManager::appName = QString("vnote");
|
||||
const QString VConfigManager::c_version = QString("1.2");
|
||||
const QString VConfigManager::dirConfigFileName = QString(".vnote.json");
|
||||
const QString VConfigManager::defaultConfigFilePath = QString(":/resources/vnote.ini");
|
||||
const QString VConfigManager::c_styleConfigFolder = QString("styles");
|
||||
const QString VConfigManager::c_defaultCssFile = QString(":/resources/styles/default.css");
|
||||
|
||||
VConfigManager::VConfigManager()
|
||||
: userSettings(NULL), defaultSettings(NULL)
|
||||
@ -31,11 +33,24 @@ VConfigManager::~VConfigManager()
|
||||
}
|
||||
}
|
||||
|
||||
void VConfigManager::migrateIniFile()
|
||||
{
|
||||
const QString originalFolder = "tamlok";
|
||||
const QString newFolder = orgName;
|
||||
QString configFolder = getConfigFolder();
|
||||
QDir dir(configFolder);
|
||||
dir.cdUp();
|
||||
dir.rename(originalFolder, newFolder);
|
||||
}
|
||||
|
||||
void VConfigManager::initialize()
|
||||
{
|
||||
userSettings = new QSettings(QSettings::IniFormat, QSettings::UserScope, orgName, appName);
|
||||
userSettings = new QSettings(QSettings::IniFormat, QSettings::UserScope,
|
||||
orgName, appName);
|
||||
defaultSettings = new QSettings(defaultConfigFilePath, QSettings::IniFormat);
|
||||
|
||||
migrateIniFile();
|
||||
|
||||
m_editorFontSize = getConfigFromSettings("global", "editor_font_size").toInt();
|
||||
if (m_editorFontSize <= 0) {
|
||||
m_editorFontSize = 12;
|
||||
@ -44,7 +59,7 @@ void VConfigManager::initialize()
|
||||
baseEditPalette = QTextEdit().palette();
|
||||
|
||||
welcomePagePath = getConfigFromSettings("global", "welcome_page_path").toString();
|
||||
templateCssUrl = getConfigFromSettings("global", "template_css_url").toString();
|
||||
m_templateCss = getConfigFromSettings("global", "template_css").toString();
|
||||
curNotebookIndex = getConfigFromSettings("global", "current_notebook").toInt();
|
||||
|
||||
markdownExtensions = hoedown_extensions(HOEDOWN_EXT_TABLES | HOEDOWN_EXT_FENCED_CODE |
|
||||
@ -311,3 +326,84 @@ void VConfigManager::setWebZoomFactor(qreal p_factor)
|
||||
setConfigToSettings("global", "web_zoom_factor", m_webZoomFactor);
|
||||
}
|
||||
|
||||
QString VConfigManager::getConfigFolder() const
|
||||
{
|
||||
V_ASSERT(userSettings);
|
||||
|
||||
QString iniPath = userSettings->fileName();
|
||||
return VUtils::basePathFromPath(iniPath);
|
||||
}
|
||||
|
||||
QString VConfigManager::getStyleConfigFolder() const
|
||||
{
|
||||
return getConfigFolder() + QDir::separator() + c_styleConfigFolder;
|
||||
}
|
||||
|
||||
QVector<QString> VConfigManager::getCssStyles() const
|
||||
{
|
||||
QVector<QString> res;
|
||||
QDir dir(getStyleConfigFolder());
|
||||
if (!dir.exists()) {
|
||||
// Output pre-defined css styles to this folder.
|
||||
outputDefaultCssStyle();
|
||||
}
|
||||
|
||||
// Get all the .css files in the folder.
|
||||
dir.setFilter(QDir::Files | QDir::NoSymLinks);
|
||||
dir.setNameFilters(QStringList("*.css"));
|
||||
QStringList files = dir.entryList();
|
||||
res.reserve(files.size());
|
||||
for (auto const &item : files) {
|
||||
res.push_back(item.left(item.size() - 4));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
bool VConfigManager::outputDefaultCssStyle() const
|
||||
{
|
||||
// Make sure the styles folder exists.
|
||||
QDir dir(getConfigFolder());
|
||||
if (!dir.exists(c_styleConfigFolder)) {
|
||||
if (!dir.mkdir(c_styleConfigFolder)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return VUtils::copyFile(c_defaultCssFile,
|
||||
getStyleConfigFolder() + QDir::separator() + "default.css",
|
||||
false);
|
||||
}
|
||||
|
||||
QString VConfigManager::getTemplateCssUrl()
|
||||
{
|
||||
QString cssPath = getStyleConfigFolder() + QDir::separator() + m_templateCss + ".css";
|
||||
if (!QFile::exists(cssPath)) {
|
||||
// Specified css not exists.
|
||||
if (m_templateCss == "default") {
|
||||
bool ret = outputDefaultCssStyle();
|
||||
if (!ret) {
|
||||
// Use embedded file.
|
||||
cssPath = "qrc" + c_defaultCssFile;
|
||||
}
|
||||
} else {
|
||||
setTemplateCss("default");
|
||||
return getTemplateCssUrl();
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "use template css:" << cssPath;
|
||||
return cssPath;
|
||||
}
|
||||
|
||||
const QString &VConfigManager::getTemplateCss() const
|
||||
{
|
||||
return m_templateCss;
|
||||
}
|
||||
|
||||
void VConfigManager::setTemplateCss(const QString &p_css)
|
||||
{
|
||||
if (m_templateCss == p_css) {
|
||||
return;
|
||||
}
|
||||
m_templateCss = p_css;
|
||||
setConfigToSettings("global", "template_css", m_templateCss);
|
||||
}
|
||||
|
@ -54,7 +54,10 @@ public:
|
||||
|
||||
inline QString getWelcomePagePath() const;
|
||||
|
||||
inline QString getTemplateCssUrl() const;
|
||||
QString getTemplateCssUrl();
|
||||
|
||||
const QString &getTemplateCss() const;
|
||||
void setTemplateCss(const QString &p_css);
|
||||
|
||||
inline QFont getBaseEditFont() const;
|
||||
inline QPalette getBaseEditPalette() const;
|
||||
@ -140,6 +143,15 @@ public:
|
||||
inline bool getEnableCodeBlockHighlight() const;
|
||||
inline void setEnableCodeBlockHighlight(bool p_enabled);
|
||||
|
||||
// Get the folder the ini file exists.
|
||||
QString getConfigFolder() const;
|
||||
|
||||
// Get the folder c_styleConfigFolder in the config folder.
|
||||
QString getStyleConfigFolder() const;
|
||||
|
||||
// Read all available css files in c_styleConfigFolder.
|
||||
QVector<QString> getCssStyles() const;
|
||||
|
||||
private:
|
||||
void updateMarkdownEditStyle();
|
||||
QVariant getConfigFromSettings(const QString §ion, const QString &key);
|
||||
@ -150,6 +162,12 @@ private:
|
||||
// Update baseEditPalette according to curBackgroundColor
|
||||
void updatePaletteColor();
|
||||
|
||||
// Migrate ini file from tamlok/vnote.ini to vnote/vnote.ini.
|
||||
// This is for the change of org name.
|
||||
void migrateIniFile();
|
||||
|
||||
bool outputDefaultCssStyle() const;
|
||||
|
||||
int m_editorFontSize;
|
||||
QFont baseEditFont;
|
||||
QPalette baseEditPalette;
|
||||
@ -158,7 +176,7 @@ private:
|
||||
QVector<HighlightingStyle> mdHighlightingStyles;
|
||||
QMap<QString, QTextCharFormat> m_codeBlockStyles;
|
||||
QString welcomePagePath;
|
||||
QString templateCssUrl;
|
||||
QString m_templateCss;
|
||||
int curNotebookIndex;
|
||||
|
||||
// Markdown Converter
|
||||
@ -230,6 +248,9 @@ private:
|
||||
QSettings *userSettings;
|
||||
// Qsettings for @defaultConfigFileName
|
||||
QSettings *defaultSettings;
|
||||
// The folder name of style files.
|
||||
static const QString c_styleConfigFolder;
|
||||
static const QString c_defaultCssFile;
|
||||
};
|
||||
|
||||
|
||||
@ -258,11 +279,6 @@ inline QString VConfigManager::getWelcomePagePath() const
|
||||
return welcomePagePath;
|
||||
}
|
||||
|
||||
inline QString VConfigManager::getTemplateCssUrl() const
|
||||
{
|
||||
return templateCssUrl;
|
||||
}
|
||||
|
||||
inline QFont VConfigManager::getBaseEditFont() const
|
||||
{
|
||||
return baseEditFont;
|
||||
|
@ -348,8 +348,12 @@ void VMainWindow::initMarkdownMenu()
|
||||
Q_ASSERT(false);
|
||||
}
|
||||
|
||||
initRenderStyleMenu(markdownMenu);
|
||||
|
||||
initRenderBackgroundMenu(markdownMenu);
|
||||
|
||||
markdownMenu->addSeparator();
|
||||
|
||||
QAction *mermaidAct = new QAction(tr("&Mermaid Diagram"), this);
|
||||
mermaidAct->setToolTip(tr("Enable Mermaid for graph and diagram"));
|
||||
mermaidAct->setCheckable(true);
|
||||
@ -359,8 +363,8 @@ void VMainWindow::initMarkdownMenu()
|
||||
|
||||
mermaidAct->setChecked(vconfig.getEnableMermaid());
|
||||
|
||||
QAction *mathjaxAct = new QAction(tr("Math&jax"), this);
|
||||
mathjaxAct->setToolTip(tr("Enable Mathjax for math support in Markdown"));
|
||||
QAction *mathjaxAct = new QAction(tr("Math&Jax"), this);
|
||||
mathjaxAct->setToolTip(tr("Enable MathJax for math support in Markdown"));
|
||||
mathjaxAct->setCheckable(true);
|
||||
connect(mathjaxAct, &QAction::triggered,
|
||||
this, &VMainWindow::enableMathjax);
|
||||
@ -767,6 +771,37 @@ void VMainWindow::initRenderBackgroundMenu(QMenu *menu)
|
||||
}
|
||||
}
|
||||
|
||||
void VMainWindow::initRenderStyleMenu(QMenu *p_menu)
|
||||
{
|
||||
QMenu *styleMenu = p_menu->addMenu(tr("Rendering &Style"));
|
||||
styleMenu->setToolTipsVisible(true);
|
||||
|
||||
QActionGroup *styleAct = new QActionGroup(this);
|
||||
connect(styleAct, &QActionGroup::triggered,
|
||||
this, &VMainWindow::setRenderStyle);
|
||||
|
||||
bool foundCurrentCss = false;
|
||||
QVector<QString> styles = vconfig.getCssStyles();
|
||||
for (auto const &style : styles) {
|
||||
QAction *act = new QAction(style, styleAct);
|
||||
act->setToolTip(tr("Set as the CSS style for Markdown rendering"));
|
||||
act->setCheckable(true);
|
||||
act->setData(style);
|
||||
|
||||
if (vconfig.getTemplateCss() == style) {
|
||||
act->setChecked(true);
|
||||
foundCurrentCss = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundCurrentCss && styles.isEmpty()) {
|
||||
delete styleAct;
|
||||
return;
|
||||
}
|
||||
|
||||
styleMenu->addActions(styleAct->actions());
|
||||
}
|
||||
|
||||
void VMainWindow::initEditorBackgroundMenu(QMenu *menu)
|
||||
{
|
||||
QMenu *backgroundColorMenu = menu->addMenu(tr("&Background Color"));
|
||||
@ -810,6 +845,15 @@ void VMainWindow::setRenderBackgroundColor(QAction *action)
|
||||
vnote->updateTemplate();
|
||||
}
|
||||
|
||||
void VMainWindow::setRenderStyle(QAction *p_action)
|
||||
{
|
||||
if (!p_action) {
|
||||
return;
|
||||
}
|
||||
vconfig.setTemplateCss(p_action->data().toString());
|
||||
vnote->updateTemplate();
|
||||
}
|
||||
|
||||
void VMainWindow::updateActionStateFromTabStatusChange(const VFile *p_file,
|
||||
bool p_editMode)
|
||||
{
|
||||
|
@ -52,6 +52,7 @@ private slots:
|
||||
void setTabStopWidth(QAction *action);
|
||||
void setEditorBackgroundColor(QAction *action);
|
||||
void setRenderBackgroundColor(QAction *action);
|
||||
void setRenderStyle(QAction *p_action);
|
||||
void changeHighlightCursorLine(bool p_checked);
|
||||
void changeHighlightSelectedWord(bool p_checked);
|
||||
void changeHighlightSearchedWord(bool p_checked);
|
||||
@ -97,6 +98,7 @@ private:
|
||||
void initAvatar();
|
||||
void initPredefinedColorPixmaps();
|
||||
void initRenderBackgroundMenu(QMenu *menu);
|
||||
void initRenderStyleMenu(QMenu *p_menu);
|
||||
void initEditorBackgroundMenu(QMenu *menu);
|
||||
void changeSplitterView(int nrPanel);
|
||||
void updateWindowTitle(const QString &str);
|
||||
|
@ -157,7 +157,7 @@ void VNote::updateTemplate()
|
||||
}
|
||||
QString cssStyle;
|
||||
if (!rgb.isEmpty()) {
|
||||
cssStyle = "body { background-color: #" + rgb + "; }";
|
||||
cssStyle = "body { background-color: #" + rgb + " !important; }";
|
||||
}
|
||||
QString styleHolder("<!-- BACKGROUND_PLACE_HOLDER -->");
|
||||
QString cssHolder("CSS_PLACE_HOLDER");
|
||||
|
@ -2,7 +2,6 @@
|
||||
<qresource prefix="/">
|
||||
<file>resources/welcome.html</file>
|
||||
<file>resources/qwebchannel.js</file>
|
||||
<file>resources/markdown.css</file>
|
||||
<file>utils/marked/marked.min.js</file>
|
||||
<file>utils/highlightjs/highlight.pack.js</file>
|
||||
<file>utils/highlightjs/styles/androidstudio.css</file>
|
||||
@ -99,5 +98,6 @@
|
||||
<file>resources/icons/float.svg</file>
|
||||
<file>resources/docs/shortcuts_en.md</file>
|
||||
<file>resources/docs/shortcuts_zh.md</file>
|
||||
<file>resources/styles/default.css</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
x
Reference in New Issue
Block a user