support spell check (#1754)

This commit is contained in:
Le Tan 2021-05-08 19:38:42 -07:00 committed by GitHub
parent 8955afae66
commit 6dbc688773
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 50154 additions and 151 deletions

@ -1 +1 @@
Subproject commit d4a2b99607023810e0e60cbab643db3b647417dc
Subproject commit 9b9aa9dd1d8ebec02daee23cb26d0b12ae00cf69

View File

@ -219,6 +219,12 @@ void ConfigMgr::checkAppConfig()
FileUtils::copyDir(extraDataRoot + QStringLiteral("/web"),
appConfigDir.filePath(QStringLiteral("web")));
// Copy dicts.
qApp->processEvents();
splash->showMessage("Copying dicts");
FileUtils::copyDir(extraDataRoot + QStringLiteral("/dicts"),
appConfigDir.filePath(QStringLiteral("dicts")));
// Main config file.
FileUtils::copyFile(getConfigFilePath(Source::Default), appConfigDir.filePath(c_configFileName));
@ -356,8 +362,24 @@ QString ConfigMgr::getAppSyntaxHighlightingFolder() const
QString ConfigMgr::getUserSyntaxHighlightingFolder() const
{
return PathUtils::concatenateFilePath(m_userConfigFolderPath,
auto folderPath = PathUtils::concatenateFilePath(m_userConfigFolderPath,
QStringLiteral("syntax-highlighting"));
QDir().mkpath(folderPath);
return folderPath;
}
QString ConfigMgr::getAppDictsFolder() const
{
return PathUtils::concatenateFilePath(m_appConfigFolderPath,
QStringLiteral("dicts"));
}
QString ConfigMgr::getUserDictsFolder() const
{
auto folderPath = PathUtils::concatenateFilePath(m_userConfigFolderPath,
QStringLiteral("dicts"));
QDir().mkpath(folderPath);
return folderPath;
}
QString ConfigMgr::getUserOrAppFile(const QString &p_filePath) const

View File

@ -89,6 +89,9 @@ namespace vnotex
QString getUserSyntaxHighlightingFolder() const;
QString getAppDictsFolder() const;
QString getUserDictsFolder() const;
// If @p_filePath is absolute, just return it.
// Otherwise, first try to find it in user folder, then in app folder.
QString getUserOrAppFile(const QString &p_filePath) const;

View File

@ -10,6 +10,7 @@ using namespace vnotex;
#define READINT(key) readInt(appObj, userObj, (key))
#define READSTR(key) readString(appObj, userObj, (key))
#define READBOOL(key) readBool(appObj, userObj, (key))
EditorConfig::EditorConfig(ConfigMgr *p_mgr, IConfig *p_topConfig)
: IConfig(p_mgr, p_topConfig),
@ -57,6 +58,12 @@ void EditorConfig::loadCore(const QJsonObject &p_app, const QJsonObject &p_user)
m_backupFileExtension = READSTR(QStringLiteral("backup_file_extension"));
loadShortcuts(appObj, userObj);
m_spellCheckAutoDetectLanguageEnabled = READBOOL(QStringLiteral("spell_check_auto_detect_language"));
m_spellCheckDefaultDictionary = READSTR(QStringLiteral("spell_check_default_dictionary"));
if (m_spellCheckDefaultDictionary.isEmpty()) {
m_spellCheckDefaultDictionary = QStringLiteral("en_US");
}
}
QJsonObject EditorConfig::saveCore() const
@ -67,6 +74,8 @@ QJsonObject EditorConfig::saveCore() const
obj[QStringLiteral("backup_file_directory")] = m_backupFileDirectory;
obj[QStringLiteral("backup_file_extension")] = m_backupFileExtension;
obj[QStringLiteral("shortcuts")] = saveShortcuts();
obj[QStringLiteral("spell_check_auto_detect_language")] = m_spellCheckAutoDetectLanguageEnabled;
obj[QStringLiteral("spell_check_default_dictionary")] = m_spellCheckDefaultDictionary;
return obj;
}
@ -188,3 +197,18 @@ const QString &EditorConfig::getBackupFileExtension() const
{
return m_backupFileExtension;
}
bool EditorConfig::isSpellCheckAutoDetectLanguageEnabled() const
{
return m_spellCheckAutoDetectLanguageEnabled;
}
const QString &EditorConfig::getSpellCheckDefaultDictionary() const
{
return m_spellCheckDefaultDictionary;
}
void EditorConfig::setSpellCheckDefaultDictionary(const QString &p_dict)
{
updateConfig(m_spellCheckDefaultDictionary, p_dict, this);
}

View File

@ -87,6 +87,11 @@ namespace vnotex
const QString &getShortcut(Shortcut p_shortcut) const;
bool isSpellCheckAutoDetectLanguageEnabled() const;
const QString &getSpellCheckDefaultDictionary() const;
void setSpellCheckDefaultDictionary(const QString &p_dict);
private:
void loadCore(const QJsonObject &p_app, const QJsonObject &p_user);
@ -116,6 +121,10 @@ namespace vnotex
QSharedPointer<TextEditorConfig> m_textEditorConfig;
QScopedPointer<MarkdownEditorConfig> m_markdownEditorConfig;
bool m_spellCheckAutoDetectLanguageEnabled = false;
QString m_spellCheckDefaultDictionary;
};
}

View File

@ -53,6 +53,8 @@ void MarkdownEditorConfig::init(const QJsonObject &p_app, const QJsonObject &p_u
m_smartTableEnabled = READBOOL(QStringLiteral("smart_table"));
m_smartTableInterval = READINT(QStringLiteral("smart_table_interval"));
m_spellCheckEnabled = READBOOL(QStringLiteral("spell_check"));
}
QJsonObject MarkdownEditorConfig::toJson() const
@ -81,6 +83,7 @@ QJsonObject MarkdownEditorConfig::toJson() const
obj[QStringLiteral("indent_first_line")] = m_indentFirstLineEnabled;
obj[QStringLiteral("smart_table")] = m_smartTableEnabled;
obj[QStringLiteral("smart_table_interval")] = m_smartTableInterval;
obj[QStringLiteral("spell_check")] = m_spellCheckEnabled;
return obj;
}
@ -373,3 +376,12 @@ int MarkdownEditorConfig::getSmartTableInterval() const
return m_smartTableInterval;
}
bool MarkdownEditorConfig::isSpellCheckEnabled() const
{
return m_spellCheckEnabled;
}
void MarkdownEditorConfig::setSpellCheckEnabled(bool p_enabled)
{
updateConfig(m_spellCheckEnabled, p_enabled, this);
}

View File

@ -99,6 +99,9 @@ namespace vnotex
int getSmartTableInterval() const;
bool isSpellCheckEnabled() const;
void setSpellCheckEnabled(bool p_enabled);
private:
QString sectionNumberModeToString(SectionNumberMode p_mode) const;
SectionNumberMode stringToSectionNumberMode(const QString &p_str) const;
@ -171,6 +174,9 @@ namespace vnotex
// Interval time to do smart table format.
int m_smartTableInterval = 2000;
// Override the config in TextEditorConfig.
bool m_spellCheckEnabled = true;
};
}

View File

@ -45,6 +45,8 @@ void TextEditorConfig::init(const QJsonObject &p_app,
m_tabStopWidth = READINT(QStringLiteral("tab_stop_width"));
m_zoomDelta = READINT(QStringLiteral("zoom_delta"));
m_spellCheckEnabled = READBOOL(QStringLiteral("spell_check"));
}
QJsonObject TextEditorConfig::toJson() const
@ -58,6 +60,7 @@ QJsonObject TextEditorConfig::toJson() const
obj[QStringLiteral("expand_tab")] = m_expandTab;
obj[QStringLiteral("tab_stop_width")] = m_tabStopWidth;
obj[QStringLiteral("zoom_delta")] = m_zoomDelta;
obj[QStringLiteral("spell_check")] = m_spellCheckEnabled;
return obj;
}
@ -244,3 +247,13 @@ void TextEditorConfig::setZoomDelta(int p_delta)
{
updateConfig(m_zoomDelta, p_delta, this);
}
bool TextEditorConfig::isSpellCheckEnabled() const
{
return m_spellCheckEnabled;
}
void TextEditorConfig::setSpellCheckEnabled(bool p_enabled)
{
updateConfig(m_spellCheckEnabled, p_enabled, this);
}

View File

@ -66,6 +66,9 @@ namespace vnotex
int getZoomDelta() const;
void setZoomDelta(int p_delta);
bool isSpellCheckEnabled() const;
void setSpellCheckEnabled(bool p_enabled);
private:
QString lineNumberTypeToString(LineNumberType p_type) const;
LineNumberType stringToLineNumberType(const QString &p_str) const;
@ -94,6 +97,8 @@ namespace vnotex
int m_tabStopWidth = 4;
int m_zoomDelta = 0;
bool m_spellCheckEnabled = false;
};
}

View File

@ -210,42 +210,67 @@
<context>
<name>vnotex::EditorPage</name>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="27"/>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="32"/>
<source>Auto save policy</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="29"/>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="34"/>
<source>None</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="30"/>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="35"/>
<source>Auto Save</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="31"/>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="36"/>
<source>Backup File</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="33"/>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="38"/>
<source>Auto save policy:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="42"/>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="47"/>
<source>Icon size of the editor tool bar</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="47"/>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="52"/>
<source>Tool bar icon size:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="85"/>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="64"/>
<source>Default dictionary used for spell check</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="74"/>
<source>Add Dictionary</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="80"/>
<source>VNote uses [Hunspell](http://hunspell.github.io/) for spell check.</source>
<translation>VNote 使 [Hunspell](http://hunspell.github.io/) 进行拼写检查。</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="81"/>
<source>Please download Hunspell&apos;s dictionaries, put them under (%1) and restart VNote.</source>
<translation> Hunspell (%1) VNote</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="90"/>
<source>Spell check dictionary:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/editorpage.cpp" line="136"/>
<source>Editor</source>
<translation></translation>
</message>
@ -872,7 +897,12 @@
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/importfolderdialog.cpp" line="91"/>
<location filename="../../../widgets/dialogs/importfolderdialog.cpp" line="90"/>
<source>Failed to add folder (%1) as node under (%2).</source>
<translation> (%2) (%1) </translation>
</message>
<message>
<location filename="../../../widgets/dialogs/importfolderdialog.cpp" line="100"/>
<source>Failed to add folder (%1) as node (%2).</source>
<translation> (%1) (%2)</translation>
</message>
@ -1039,48 +1069,48 @@
<context>
<name>vnotex::MainWindow</name>
<message>
<location filename="../../../widgets/mainwindow.cpp" line="241"/>
<location filename="../../../widgets/mainwindow.cpp" line="245"/>
<source>Navigation</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/mainwindow.cpp" line="255"/>
<location filename="../../../widgets/mainwindow.cpp" line="259"/>
<source>Outline</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/mainwindow.cpp" line="269"/>
<location filename="../../../widgets/mainwindow.cpp" line="273"/>
<source>Search</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/mainwindow.cpp" line="293"/>
<location filename="../../../widgets/mainwindow.cpp" line="297"/>
<source>Location List</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/mainwindow.cpp" line="327"/>
<location filename="../../../widgets/mainwindow.cpp" line="331"/>
<source>Notebooks</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/mainwindow.cpp" line="395"/>
<location filename="../../../widgets/mainwindow.cpp" line="399"/>
<source>Do you want to minimize %1 to system tray instead of quitting when closed?</source>
<translation> %1 退</translation>
</message>
<message>
<location filename="../../../widgets/mainwindow.cpp" line="397"/>
<location filename="../../../widgets/mainwindow.cpp" line="401"/>
<source>You could change the option in Settings later.</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/mainwindow.cpp" line="433"/>
<location filename="../../../widgets/mainwindow.cpp" line="437"/>
<source>%1 is still running here.</source>
<translation>%1 </translation>
</message>
<message>
<location filename="../../../widgets/mainwindow.cpp" line="553"/>
<location filename="../../../widgets/mainwindow.cpp" line="561"/>
<location filename="../../../widgets/mainwindow.cpp" line="575"/>
<location filename="../../../widgets/mainwindow.cpp" line="583"/>
<source>Global</source>
<translation></translation>
</message>
@ -1341,44 +1371,44 @@
<translation>()</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="222"/>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="233"/>
<source>Close notebook (%1)?</source>
<translation> (%1)</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="224"/>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="235"/>
<source>The notebook could be imported again later.</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="225"/>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="236"/>
<source>Notebook location: %1</source>
<translation>: %1</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="236"/>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="247"/>
<source>Failed to close notebook (%1)</source>
<translation> (%1)</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="249"/>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="263"/>
<source>Delete notebook (%1) from disk?</source>
<translation> (%1)?</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="250"/>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="264"/>
<source>CALM DOWN! CALM DOWN! CALM DOWN! It will delete all files belonging to this notebook from disk. It is dangerous since it will bypass system&apos;s recycle bin!</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="252"/>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="266"/>
<source>Notebook location: %1
Use the &quot;Close&quot; button if you just want to remove it from %2.</source>
<translation>: %1
%2 使</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="264"/>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="278"/>
<source>Failed to delete notebook (%1)</source>
<translation> (%1)</translation>
</message>
@ -1391,7 +1421,7 @@ Use the &quot;Close&quot; button if you just want to remove it from %2.</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="277"/>
<location filename="../../../widgets/dialogs/managenotebooksdialog.cpp" line="291"/>
<source>There are unsaved changes to current notebook.</source>
<translation></translation>
</message>
@ -1399,129 +1429,129 @@ Use the &quot;Close&quot; button if you just want to remove it from %2.</source>
<context>
<name>vnotex::MarkdownEditor</name>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="240"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="674"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="241"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="675"/>
<source>Insert Link</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="253"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="254"/>
<source>Insert Image</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="310"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="311"/>
<source>Insert Table</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="449"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="450"/>
<source>For advanced paste, try the &quot;Rich Paste&quot; and &quot;Parse To Markdown And Paste&quot; on the editor&apos;s context menu</source>
<translation> Markdown </translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="483"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="520"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="586"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="484"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="521"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="587"/>
<source>Insert From Clipboard</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="484"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="485"/>
<source>Insert From URL</source>
<translation>URL插入</translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="485"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="486"/>
<source>Insert From Image Data</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="486"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="523"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="589"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="487"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="524"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="590"/>
<source>Insert As Image Link</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="521"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="588"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="522"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="589"/>
<source>Insert As Image</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="522"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="604"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="523"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="605"/>
<source>Insert As Text</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="591"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="592"/>
<source>Insert As Relative Image Link</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="595"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="596"/>
<source>Insert As Link</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="597"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="598"/>
<source>Insert As Relative Link</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="600"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="601"/>
<source>Attach And Insert Link</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="606"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="607"/>
<source>Insert File Content</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="727"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="728"/>
<source>Insert Image From Clipboard</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="740"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="741"/>
<source>Insert Image From URL</source>
<translation>URL插入图片</translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="929"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="930"/>
<source>&amp;Read</source>
<translation>(&amp;R)</translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="945"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="946"/>
<source>Rich Paste</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="954"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="955"/>
<source>Parse To Markdown And Paste</source>
<translation> Markodwn </translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="1029"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="1032"/>
<source>Fetching images to local...</source>
<translation>...</translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="1030"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="1033"/>
<source>Abort</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="1035"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="1038"/>
<source>Fetch Images To Local</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="1060"/>
<location filename="../../../widgets/editors/markdowneditor.cpp" line="1063"/>
<source>Fetching image (%1)</source>
<translation> (%1)</translation>
</message>
@ -1529,12 +1559,12 @@ Use the &quot;Close&quot; button if you just want to remove it from %2.</source>
<context>
<name>vnotex::MarkdownEditorPage</name>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="203"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="207"/>
<source>Insert file name as title</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="205"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="209"/>
<source>Insert file name as title when creating note</source>
<translation></translation>
</message>
@ -1547,149 +1577,155 @@ Use the &quot;Close&quot; button if you just want to remove it from %2.</source>
<translation type="vanished"></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="127"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="256"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="131"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="270"/>
<source>Read</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="131"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="135"/>
<source>Constrain image width</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="133"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="137"/>
<source>Constrain image width to the window</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="142"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="146"/>
<source>Zoom factor in read mode</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="147"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="151"/>
<source>Zoom factor:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="155"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="159"/>
<source>HTML tag</source>
<translation>HTML </translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="157"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="161"/>
<source>Allow HTML tags in source</source>
<translation> HTML </translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="165"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="169"/>
<source>Auto break</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="167"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="171"/>
<source>Automatically break a line with &apos;\n&apos;</source>
<translation> &apos;\n&apos; </translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="175"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="179"/>
<source>Linkify</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="177"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="181"/>
<source>Convert URL-like text to links</source>
<translation> URL </translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="185"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="189"/>
<source>Indent first line</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="187"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="191"/>
<source>Indent the first line of each paragraph</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="199"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="257"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="203"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="271"/>
<source>Edit</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="213"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="217"/>
<source>Constrain in-place preview width</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="215"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="219"/>
<source>Constrain in-place preview width to the window</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="223"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="227"/>
<source>Fetch images to local in Parse And Paste</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="225"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="229"/>
<source>Fetch images to local in Parse To Markdown And Paste</source>
<translation> Markdown </translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="233"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="237"/>
<source>Smart table</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="235"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="239"/>
<source>Smart table formation</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="247"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="249"/>
<source>Spell check</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="261"/>
<source>General</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="254"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="268"/>
<source>Section number mode</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="255"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="269"/>
<source>None</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="263"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="277"/>
<source>Base level to start section numbering in edit mode</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="271"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="285"/>
<source>Section number style</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="272"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="286"/>
<source>1.1.</source>
<translation>1.1.</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="273"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="287"/>
<source>1.1</source>
<translation>1.1</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="284"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="298"/>
<source>Section number:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="122"/>
<location filename="../../../widgets/dialogs/settings/markdowneditorpage.cpp" line="126"/>
<source>Markdown Editor</source>
<translation>Markdown </translation>
</message>
@ -1701,28 +1737,28 @@ Use the &quot;Close&quot; button if you just want to remove it from %2.</source>
<translation type="vanished">Markdown </translation>
</message>
<message>
<location filename="../../../widgets/markdownviewwindow.cpp" line="394"/>
<location filename="../../../widgets/markdownviewwindow.cpp" line="395"/>
<source>Markdown Viewer</source>
<translation>Markdown </translation>
</message>
<message>
<location filename="../../../widgets/markdownviewwindow.cpp" line="719"/>
<location filename="../../../widgets/markdownviewwindow.cpp" line="720"/>
<source>Clear Obsolete Images</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/markdownviewwindow.cpp" line="720"/>
<location filename="../../../widgets/markdownviewwindow.cpp" line="721"/>
<source>These images seems not in use anymore. Please confirm the deletion of them.</source>
<translation>使</translation>
</message>
<message>
<location filename="../../../widgets/markdownviewwindow.cpp" line="721"/>
<location filename="../../../widgets/markdownviewwindow.cpp" line="722"/>
<source>Deleted images could be found in the recycle bin of notebook if it is from a bundle notebook.</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/markdownviewwindow.cpp" line="853"/>
<location filename="../../../widgets/markdownviewwindow.cpp" line="862"/>
<location filename="../../../widgets/markdownviewwindow.cpp" line="863"/>
<location filename="../../../widgets/markdownviewwindow.cpp" line="872"/>
<source>Replace is not supported in read mode</source>
<translation></translation>
</message>
@ -2582,167 +2618,167 @@ Description: %3</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="86"/>
<location filename="../../../widgets/searchpanel.cpp" line="87"/>
<source>Keyword:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="89"/>
<location filename="../../../widgets/searchpanel.cpp" line="90"/>
<source>Buffers</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="90"/>
<location filename="../../../widgets/searchpanel.cpp" line="91"/>
<source>Current Folder</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="91"/>
<location filename="../../../widgets/searchpanel.cpp" line="92"/>
<source>Current Notebook</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="92"/>
<location filename="../../../widgets/searchpanel.cpp" line="93"/>
<source>All Notebooks</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="93"/>
<location filename="../../../widgets/searchpanel.cpp" line="94"/>
<source>Scope:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="110"/>
<location filename="../../../widgets/searchpanel.cpp" line="111"/>
<source>Wildcard pattern of files to search</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="113"/>
<location filename="../../../widgets/searchpanel.cpp" line="114"/>
<source>File pattern:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="135"/>
<location filename="../../../widgets/searchpanel.cpp" line="136"/>
<source>Search</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="139"/>
<location filename="../../../widgets/searchpanel.cpp" line="140"/>
<source>Cancel</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="143"/>
<location filename="../../../widgets/searchpanel.cpp" line="144"/>
<source>Toggle Location List</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="149"/>
<location filename="../../../widgets/searchpanel.cpp" line="150"/>
<source>Advanced Settings</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="164"/>
<location filename="../../../widgets/searchpanel.cpp" line="165"/>
<source>Object:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="166"/>
<location filename="../../../widgets/searchpanel.cpp" line="167"/>
<source>Name</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="169"/>
<location filename="../../../widgets/searchpanel.cpp" line="170"/>
<source>Content</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="172"/>
<location filename="../../../widgets/searchpanel.cpp" line="173"/>
<source>Outline</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="175"/>
<location filename="../../../widgets/searchpanel.cpp" line="176"/>
<source>Tag</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="178"/>
<location filename="../../../widgets/searchpanel.cpp" line="179"/>
<source>Path</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="186"/>
<location filename="../../../widgets/searchpanel.cpp" line="187"/>
<source>Target:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="188"/>
<location filename="../../../widgets/searchpanel.cpp" line="189"/>
<source>File</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="191"/>
<location filename="../../../widgets/searchpanel.cpp" line="192"/>
<source>Folder</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="194"/>
<location filename="../../../widgets/searchpanel.cpp" line="195"/>
<source>Notebook</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="202"/>
<location filename="../../../widgets/searchpanel.cpp" line="203"/>
<source>Option:</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="204"/>
<location filename="../../../widgets/searchpanel.cpp" line="205"/>
<source>&amp;Case sensitive</source>
<translation>(&amp;C)</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="210"/>
<location filename="../../../widgets/searchpanel.cpp" line="211"/>
<source>&amp;Plain text</source>
<translation>(&amp;P)</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="214"/>
<location filename="../../../widgets/searchpanel.cpp" line="215"/>
<source>&amp;Whole word only</source>
<translation>(&amp;W)</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="218"/>
<location filename="../../../widgets/searchpanel.cpp" line="219"/>
<source>&amp;Fuzzy search</source>
<translation>(&amp;F)</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="222"/>
<location filename="../../../widgets/searchpanel.cpp" line="223"/>
<source>Re&amp;gular expression</source>
<translation>(&amp;G)</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="319"/>
<location filename="../../../widgets/searchpanel.cpp" line="320"/>
<source>Search finished: %1</source>
<translation>: %1</translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="491"/>
<location filename="../../../widgets/searchpanel.cpp" line="492"/>
<source>Invalid keyword</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="496"/>
<location filename="../../../widgets/searchpanel.cpp" line="497"/>
<source>No object specified</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="501"/>
<location filename="../../../widgets/searchpanel.cpp" line="502"/>
<source>No target specified</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/searchpanel.cpp" line="507"/>
<location filename="../../../widgets/searchpanel.cpp" line="508"/>
<source>Fuzzy search is not allowed when searching content</source>
<translation></translation>
</message>
@ -3051,7 +3087,13 @@ Description: %3</source>
<translation>:</translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/texteditorpage.cpp" line="211"/>
<location filename="../../../widgets/dialogs/settings/texteditorpage.cpp" line="137"/>
<location filename="../../../widgets/dialogs/settings/texteditorpage.cpp" line="139"/>
<source>Spell check</source>
<translation></translation>
</message>
<message>
<location filename="../../../widgets/dialogs/settings/texteditorpage.cpp" line="225"/>
<source>Text Editor</source>
<translation></translation>
</message>

View File

@ -75,7 +75,9 @@
"FindAndReplace" : "Ctrl+F",
"FindNext" : "F3",
"FindPrevious" : "Shift+F3"
}
},
"spell_check_auto_detect_language" : false,
"spell_check_default_dictionary" : "en_US"
},
"text_editor" : {
"theme" : "",
@ -91,7 +93,8 @@
"expand_tab": true,
"tab_stop_width": 4,
"//comment" : "Positive to zoom in and negative to zoom out",
"zoom_delta": 0
"zoom_delta": 0,
"spell_check": false
},
"markdown_editor" : {
"override_viewer_resource" : true,
@ -290,7 +293,8 @@
"//comment" : "Whether enable smart table (formatting)",
"smart_table" : true,
"//comment" : "Time interval (milliseconds) to do smart table formatting",
"smart_table_interval" : 1000
"smart_table_interval" : 1000,
"spell_check" : true
}
},
"widget" : {

View File

@ -0,0 +1,205 @@
SET UTF-8
TRY esianrtolcdugmphbyfvkwzESIANRTOLCDUGMPHBYFVKWZ'
ICONV 1
ICONV '
NOSUGGEST !
# ordinal numbers
COMPOUNDMIN 1
# only in compounds: 1th, 2th, 3th
ONLYINCOMPOUND c
# compound rules:
# 1. [0-9]*1[0-9]th (10th, 11th, 12th, 56714th, etc.)
# 2. [0-9]*[02-9](1st|2nd|3rd|[4-9]th) (21st, 22nd, 123rd, 1234th, etc.)
COMPOUNDRULE 2
COMPOUNDRULE n*1t
COMPOUNDRULE n*mp
WORDCHARS 0123456789
PFX A Y 1
PFX A 0 re .
PFX I Y 1
PFX I 0 in .
PFX U Y 1
PFX U 0 un .
PFX C Y 1
PFX C 0 de .
PFX E Y 1
PFX E 0 dis .
PFX F Y 1
PFX F 0 con .
PFX K Y 1
PFX K 0 pro .
SFX V N 2
SFX V e ive e
SFX V 0 ive [^e]
SFX N Y 3
SFX N e ion e
SFX N y ication y
SFX N 0 en [^ey]
SFX X Y 3
SFX X e ions e
SFX X y ications y
SFX X 0 ens [^ey]
SFX H N 2
SFX H y ieth y
SFX H 0 th [^y]
SFX Y Y 1
SFX Y 0 ly .
SFX G Y 2
SFX G e ing e
SFX G 0 ing [^e]
SFX J Y 2
SFX J e ings e
SFX J 0 ings [^e]
SFX D Y 4
SFX D 0 d e
SFX D y ied [^aeiou]y
SFX D 0 ed [^ey]
SFX D 0 ed [aeiou]y
SFX T N 4
SFX T 0 st e
SFX T y iest [^aeiou]y
SFX T 0 est [aeiou]y
SFX T 0 est [^ey]
SFX R Y 4
SFX R 0 r e
SFX R y ier [^aeiou]y
SFX R 0 er [aeiou]y
SFX R 0 er [^ey]
SFX Z Y 4
SFX Z 0 rs e
SFX Z y iers [^aeiou]y
SFX Z 0 ers [aeiou]y
SFX Z 0 ers [^ey]
SFX S Y 4
SFX S y ies [^aeiou]y
SFX S 0 s [aeiou]y
SFX S 0 es [sxzh]
SFX S 0 s [^sxzhy]
SFX P Y 3
SFX P y iness [^aeiou]y
SFX P 0 ness [aeiou]y
SFX P 0 ness [^y]
SFX M Y 1
SFX M 0 's .
SFX B Y 3
SFX B 0 able [^aeiou]
SFX B 0 able ee
SFX B e able [^aeiou]e
SFX L Y 1
SFX L 0 ment .
REP 90
REP a ei
REP ei a
REP a ey
REP ey a
REP ai ie
REP ie ai
REP alot a_lot
REP are air
REP are ear
REP are eir
REP air are
REP air ere
REP ere air
REP ere ear
REP ere eir
REP ear are
REP ear air
REP ear ere
REP eir are
REP eir ere
REP ch te
REP te ch
REP ch ti
REP ti ch
REP ch tu
REP tu ch
REP ch s
REP s ch
REP ch k
REP k ch
REP f ph
REP ph f
REP gh f
REP f gh
REP i igh
REP igh i
REP i uy
REP uy i
REP i ee
REP ee i
REP j di
REP di j
REP j gg
REP gg j
REP j ge
REP ge j
REP s ti
REP ti s
REP s ci
REP ci s
REP k cc
REP cc k
REP k qu
REP qu k
REP kw qu
REP o eau
REP eau o
REP o ew
REP ew o
REP oo ew
REP ew oo
REP ew ui
REP ui ew
REP oo ui
REP ui oo
REP ew u
REP u ew
REP oo u
REP u oo
REP u oe
REP oe u
REP u ieu
REP ieu u
REP ue ew
REP ew ue
REP uff ough
REP oo ieu
REP ieu oo
REP ier ear
REP ear ier
REP ear air
REP air ear
REP w qu
REP qu w
REP z ss
REP ss z
REP shun tion
REP shun sion
REP shun cion
REP size cise

49525
src/data/extra/dicts/en_US.dic Normal file

File diff suppressed because it is too large Load Diff

View File

@ -70,6 +70,8 @@
<file>web/js/turndown.js</file>
<file>web/js/mark.js/mark.min.js</file>
<file>web/js/markjs.js</file>
<file>dicts/en_US.aff</file>
<file>dicts/en_US.dic</file>
<file>themes/native/text-editor.theme</file>
<file>themes/native/highlight.css</file>
<file>themes/native/interface.qss</file>

View File

@ -4,11 +4,16 @@
#include <QFormLayout>
#include <QTimer>
#include <QSpinBox>
#include <QHBoxLayout>
#include <QPushButton>
#include <QUrl>
#include <widgets/widgetsfactory.h>
#include <core/editorconfig.h>
#include <core/configmgr.h>
#include <utils/widgetutils.h>
#include <vtextedit/spellchecker.h>
#include <widgets/messageboxhelper.h>
using namespace vnotex;
@ -51,6 +56,43 @@ void EditorPage::setupUI()
this, &EditorPage::pageIsChanged);
}
{
auto lineLayout = new QHBoxLayout();
m_spellCheckDictComboBox = WidgetsFactory::createComboBox(this);
m_spellCheckDictComboBox->setToolTip(tr("Default dictionary used for spell check"));
lineLayout->addWidget(m_spellCheckDictComboBox);
{
auto dicts = vte::SpellChecker::getInst().availableDictionaries();
for (auto it = dicts.constBegin(); it != dicts.constEnd(); ++it) {
m_spellCheckDictComboBox->addItem(it.key(), it.value());
}
}
auto addBtn = new QPushButton(tr("Add Dictionary"), this);
connect(addBtn, &QPushButton::clicked,
this, [this]() {
const auto dictsFolder = ConfigMgr::getInst().getUserDictsFolder();
MessageBoxHelper::notify(
MessageBoxHelper::Information,
tr("VNote uses [Hunspell](http://hunspell.github.io/) for spell check."),
tr("Please download Hunspell's dictionaries, put them under (%1) and restart VNote.").arg(dictsFolder),
QString(),
this);
WidgetUtils::openUrlByDesktop(QUrl::fromLocalFile(dictsFolder));
});
lineLayout->addWidget(addBtn);
lineLayout->addStretch();
const QString label(tr("Spell check dictionary:"));
mainLayout->addRow(label, lineLayout);
addSearchItem(label, m_spellCheckDictComboBox->toolTip(), m_spellCheckDictComboBox);
connect(m_spellCheckDictComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &EditorPage::pageIsChanged);
}
}
void EditorPage::loadInternal()
@ -64,6 +106,11 @@ void EditorPage::loadInternal()
}
m_toolBarIconSizeSpinBox->setValue(editorConfig.getToolBarIconSize());
{
int idx = m_spellCheckDictComboBox->findData(editorConfig.getSpellCheckDefaultDictionary());
m_spellCheckDictComboBox->setCurrentIndex(idx == -1 ? 0 : idx);
}
}
void EditorPage::saveInternal()
@ -77,6 +124,10 @@ void EditorPage::saveInternal()
editorConfig.setToolBarIconSize(m_toolBarIconSizeSpinBox->value());
{
editorConfig.setSpellCheckDefaultDictionary(m_spellCheckDictComboBox->currentData().toString());
}
notifyEditorConfigChange();
}

View File

@ -30,6 +30,8 @@ namespace vnotex
QComboBox *m_autoSavePolicyComboBox = nullptr;
QSpinBox *m_toolBarIconSizeSpinBox = nullptr;
QComboBox *m_spellCheckDictComboBox = nullptr;
};
}

View File

@ -74,6 +74,8 @@ void MarkdownEditorPage::loadInternal()
m_indentFirstLineCheckBox->setChecked(markdownConfig.getIndentFirstLineEnabled());
m_smartTableCheckBox->setChecked(markdownConfig.getSmartTableEnabled());
m_spellCheckCheckBox->setChecked(markdownConfig.isSpellCheckEnabled());
}
void MarkdownEditorPage::saveInternal()
@ -114,6 +116,8 @@ void MarkdownEditorPage::saveInternal()
markdownConfig.setSmartTableEnabled(m_smartTableCheckBox->isChecked());
markdownConfig.setSpellCheckEnabled(m_spellCheckCheckBox->isChecked());
EditorPage::notifyEditorConfigChange();
}
@ -239,6 +243,16 @@ QGroupBox *MarkdownEditorPage::setupEditGroup()
this, &MarkdownEditorPage::pageIsChanged);
}
{
const QString label(tr("Spell check"));
m_spellCheckCheckBox = WidgetsFactory::createCheckBox(label, box);
m_spellCheckCheckBox->setToolTip(tr("Spell check"));
layout->addRow(m_spellCheckCheckBox);
addSearchItem(label, m_spellCheckCheckBox->toolTip(), m_spellCheckCheckBox);
connect(m_spellCheckCheckBox, &QCheckBox::stateChanged,
this, &MarkdownEditorPage::pageIsChanged);
}
return box;
}

View File

@ -58,6 +58,8 @@ namespace vnotex
QComboBox *m_sectionNumberStyleComboBox = nullptr;
QCheckBox *m_smartTableCheckBox = nullptr;
QCheckBox *m_spellCheckCheckBox = nullptr;
};
}

View File

@ -132,6 +132,16 @@ void TextEditorPage::setupUI()
connect(m_zoomDeltaSpinBox, QOverload<int>::of(&QSpinBox::valueChanged),
this, &TextEditorPage::pageIsChanged);
}
{
const QString label(tr("Spell check"));
m_spellCheckCheckBox = WidgetsFactory::createCheckBox(label, this);
m_spellCheckCheckBox->setToolTip(tr("Spell check"));
mainLayout->addRow(m_spellCheckCheckBox);
addSearchItem(label, m_spellCheckCheckBox->toolTip(), m_spellCheckCheckBox);
connect(m_spellCheckCheckBox, &QCheckBox::stateChanged,
this, &TextEditorPage::pageIsChanged);
}
}
void TextEditorPage::loadInternal()
@ -169,6 +179,8 @@ void TextEditorPage::loadInternal()
m_tabStopWidthSpinBox->setValue(textConfig.getTabStopWidth());
m_zoomDeltaSpinBox->setValue(textConfig.getZoomDelta());
m_spellCheckCheckBox->setChecked(textConfig.isSpellCheckEnabled());
}
void TextEditorPage::saveInternal()
@ -203,6 +215,8 @@ void TextEditorPage::saveInternal()
textConfig.setZoomDelta(m_zoomDeltaSpinBox->value());
textConfig.setSpellCheckEnabled(m_spellCheckCheckBox->isChecked());
EditorPage::notifyEditorConfigChange();
}

View File

@ -40,6 +40,8 @@ namespace vnotex
QSpinBox *m_tabStopWidthSpinBox = nullptr;
QSpinBox *m_zoomDeltaSpinBox = nullptr;
QCheckBox *m_spellCheckCheckBox = nullptr;
};
}

View File

@ -66,8 +66,9 @@ MarkdownEditor::Heading::Heading(const QString &p_name,
MarkdownEditor::MarkdownEditor(const MarkdownEditorConfig &p_config,
const QSharedPointer<vte::MarkdownEditorConfig> &p_editorConfig,
const QSharedPointer<vte::TextEditorParameters> &p_editorParas,
QWidget *p_parent)
: vte::VMarkdownEditor(p_editorConfig, p_parent),
: vte::VMarkdownEditor(p_editorConfig, p_editorParas, p_parent),
m_config(p_config)
{
setupShortcuts();
@ -915,15 +916,10 @@ void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_
p_menu->reset(m_textEdit->createStandardContextMenu(p_event->pos()));
auto menu = p_menu->data();
QAction *copyAct = nullptr;
QAction *pasteAct = nullptr;
QAction *firstAct = nullptr;
{
const auto actions = menu->actions();
firstAct = actions.isEmpty() ? nullptr : actions.first();
copyAct = WidgetUtils::findActionByObjectName(actions, "edit-copy");
pasteAct = WidgetUtils::findActionByObjectName(actions, "edit-paste");
}
QAction *firstAct = actions.isEmpty() ? nullptr : actions.first();
// QAction *copyAct = WidgetUtils::findActionByObjectName(actions, "edit-copy");
QAction *pasteAct = WidgetUtils::findActionByObjectName(actions, "edit-paste");
if (!m_textEdit->hasSelection()) {
auto readAct = new QAction(tr("&Read"), menu);
@ -957,6 +953,8 @@ void MarkdownEditor::handleContextMenuEvent(QContextMenuEvent *p_event, bool *p_
WidgetUtils::insertActionAfter(menu, richPasteAct, parsePasteAct);
}
}
appendSpellCheckMenu(p_event, menu);
}
void MarkdownEditor::richPaste()

View File

@ -49,6 +49,7 @@ namespace vnotex
MarkdownEditor(const MarkdownEditorConfig &p_config,
const QSharedPointer<vte::MarkdownEditorConfig> &p_editorConfig,
const QSharedPointer<vte::TextEditorParameters> &p_editorParas,
QWidget *p_parent = nullptr);
virtual ~MarkdownEditor();

View File

@ -5,7 +5,9 @@
using namespace vnotex;
TextEditor::TextEditor(const QSharedPointer<vte::TextEditorConfig> &p_config,
const QSharedPointer<vte::TextEditorParameters> &p_paras,
QWidget *p_parent)
: vte::VTextEditor(p_config, p_parent)
: vte::VTextEditor(p_config, p_paras, p_parent)
{
enableInternalContextMenu();
}

View File

@ -10,6 +10,7 @@ namespace vnotex
Q_OBJECT
public:
TextEditor(const QSharedPointer<vte::TextEditorConfig> &p_config,
const QSharedPointer<vte::TextEditorParameters> &p_paras,
QWidget *p_parent = nullptr);
};
}

View File

@ -43,6 +43,7 @@
#include "searchpanel.h"
#include <notebook/notebook.h>
#include "searchinfoprovider.h"
#include <vtextedit/spellchecker.h>
using namespace vnotex;
@ -86,6 +87,8 @@ void MainWindow::kickOffOnStart(const QStringList &p_paths)
demoWidget();
setupSpellCheck();
openFiles(p_paths);
});
}
@ -776,3 +779,10 @@ void MainWindow::toggleLocationListVisible()
bool visible = m_docks[DockIndex::LocationListDock]->isVisible();
setLocationListVisible(!visible);
}
void MainWindow::setupSpellCheck()
{
const auto &configMgr = ConfigMgr::getInst();
vte::SpellChecker::addDictionaryCustomSearchPaths(
QStringList() << configMgr.getUserDictsFolder() << configMgr.getAppDictsFolder());
}

View File

@ -149,6 +149,8 @@ namespace vnotex
void setupDockActivateShortcut(QDockWidget *p_dock, const QString &p_keys);
void setupSpellCheck();
ToolBarHelper m_toolBarHelper;
StatusBarHelper m_statusBarHelper;

View File

@ -295,6 +295,7 @@ void MarkdownViewWindow::setupTextEditor()
m_editor = new MarkdownEditor(markdownEditorConfig,
createMarkdownEditorConfig(markdownEditorConfig),
createMarkdownEditorParameters(editorConfig, markdownEditorConfig),
this);
m_splitter->insertWidget(0, m_editor);
@ -784,6 +785,15 @@ QSharedPointer<vte::MarkdownEditorConfig> MarkdownViewWindow::createMarkdownEdit
return editorConfig;
}
QSharedPointer<vte::TextEditorParameters> MarkdownViewWindow::createMarkdownEditorParameters(const EditorConfig& p_editorConfig, const MarkdownEditorConfig &p_config)
{
auto paras = QSharedPointer<vte::TextEditorParameters>::create();
paras->m_spellCheckEnabled = p_config.isSpellCheckEnabled();
paras->m_autoDetectLanguageEnabled = p_editorConfig.isSpellCheckAutoDetectLanguageEnabled();
paras->m_defaultSpellCheckLanguage = p_editorConfig.getSpellCheckDefaultDictionary();
return paras;
}
void MarkdownViewWindow::scrollUp()
{
if (isReadMode()) {

View File

@ -11,6 +11,7 @@ class QStackedWidget;
namespace vte
{
class MarkdownEditorConfig;
struct TextEditorParameters;
}
namespace vnotex
@ -21,6 +22,7 @@ namespace vnotex
class PreviewHelper;
struct Outline;
class MarkdownEditorConfig;
class EditorConfig;
class MarkdownViewWindow : public ViewWindow
{
@ -138,6 +140,8 @@ namespace vnotex
static QSharedPointer<vte::MarkdownEditorConfig> createMarkdownEditorConfig(const MarkdownEditorConfig &p_config);
static QSharedPointer<vte::TextEditorParameters> createMarkdownEditorParameters(const EditorConfig& p_editorConfig, const MarkdownEditorConfig &p_config);
// Splitter to hold editor and viewer.
QSplitter *m_splitter = nullptr;

View File

@ -171,7 +171,7 @@ void NotebookExplorer::setCurrentNotebook(const QSharedPointer<Notebook> &p_note
{
m_currentNotebook = p_notebook;
ID id = p_notebook ? p_notebook->getId() : Notebook::InvalidId;
ID id = p_notebook ? p_notebook->getId() : static_cast<ID>(Notebook::InvalidId);
m_selector->setCurrentNotebook(id);
m_nodeExplorer->setNotebook(p_notebook);

View File

@ -35,8 +35,9 @@ void TextViewWindow::setupUI()
// Central widget.
{
auto config = createTextEditorConfig(textEditorConfig);
m_editor = new TextEditor(config, this);
m_editor = new TextEditor(createTextEditorConfig(textEditorConfig),
createTextEditorParameters(editorConfig, textEditorConfig),
this);
setCentralWidget(m_editor);
updateEditorFromConfig();
@ -161,6 +162,15 @@ QSharedPointer<vte::TextEditorConfig> TextViewWindow::createTextEditorConfig(con
return config;
}
QSharedPointer<vte::TextEditorParameters> TextViewWindow::createTextEditorParameters(const EditorConfig& p_editorConfig, const TextEditorConfig &p_config)
{
auto paras = QSharedPointer<vte::TextEditorParameters>::create();
paras->m_spellCheckEnabled = p_config.isSpellCheckEnabled();
paras->m_autoDetectLanguageEnabled = p_editorConfig.isSpellCheckAutoDetectLanguageEnabled();
paras->m_defaultSpellCheckLanguage = p_editorConfig.getSpellCheckDefaultDictionary();
return paras;
}
void TextViewWindow::scrollUp()
{
QScrollBar *vbar = m_editor->getTextEdit()->verticalScrollBar();

View File

@ -6,12 +6,14 @@
namespace vte
{
class TextEditorConfig;
struct TextEditorParameters;
}
namespace vnotex
{
class TextEditor;
class TextEditorConfig;
class EditorConfig;
class TextViewWindow : public ViewWindow
{
@ -72,6 +74,8 @@ namespace vnotex
static QSharedPointer<vte::TextEditorConfig> createTextEditorConfig(const TextEditorConfig &p_config);
static QSharedPointer<vte::TextEditorParameters> createTextEditorParameters(const EditorConfig& p_editorConfig, const TextEditorConfig &p_config);
// Managed by QObject.
TextEditor *m_editor = nullptr;

View File

@ -433,6 +433,10 @@ QAction *ViewWindow::addAction(QToolBar *p_toolBar, ViewWindowToolBarHelper::Act
});
break;
}
default:
Q_ASSERT(false);
break;
}
return act;