From ce8b8a60bbdce9f28495e5a516700eb5d4936509 Mon Sep 17 00:00:00 2001 From: xiaoyifang <105986+xiaoyifang@users.noreply.github.com> Date: Sun, 16 Jul 2023 18:54:07 +0800 Subject: [PATCH] feat: add font customization (#973) * action: auto clang format changes action: clang-format * feat: add separator tab to configure the font family for the web engine. feat: custom fonts feat: add custom font i18n: update crowdin translation files * [autofix.ci] apply automated fixes * feat: add notice about the font customization * feat: adjust interface layout * i18n: update transaltion source * fix: code smells * feat: custom font layout adjustment * i18n: update translation items * feat: adjust layout of custom fonts * i18n: new * feat: adjust layout --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- .github/workflows/auto format.yml | 9 +- locale/.clang-format | 4 + locale/crowdin.ts | 367 +++++++++--------- src/config.cc | 135 +++---- src/config.hh | 53 ++- src/ui/mainwindow.cc | 28 +- src/ui/preferences.cc | 66 ++-- src/ui/preferences.hh | 4 +- src/ui/preferences.ui | 597 ++++++++++++++++++------------ 9 files changed, 752 insertions(+), 511 deletions(-) create mode 100644 locale/.clang-format diff --git a/.github/workflows/auto format.yml b/.github/workflows/auto format.yml index f3767684..6216e75d 100644 --- a/.github/workflows/auto format.yml +++ b/.github/workflows/auto format.yml @@ -28,7 +28,7 @@ jobs: fetch-depth: 2 # format the latest commit - name: ubuntu install clang-format - if: ${{ github.event.pull_request.head.repo.full_name == 'xiaoyifang/goldendict-ng' }} + # if: ${{ github.event.pull_request.head.repo.full_name == 'xiaoyifang/goldendict-ng' }} id: clang-format run: | sudo apt-get install git lsb-release wget software-properties-common @@ -36,13 +36,6 @@ jobs: sudo apt-get update sudo apt-get install -y clang-format git-clang-format --style=file HEAD^ - - - - uses: EndBug/add-and-commit@v9 - if: ${{ github.event.pull_request.head.repo.full_name == 'xiaoyifang/goldendict-ng' }} - with: - default_author: github_actor - message: 🎨 apply clang-format changes - uses: autofix-ci/action@89762f9c25dd85f6b78cd40e521232e403357ec0 diff --git a/locale/.clang-format b/locale/.clang-format new file mode 100644 index 00000000..f54a540f --- /dev/null +++ b/locale/.clang-format @@ -0,0 +1,4 @@ +--- +DisableFormat: true +SortIncludes: Never +... diff --git a/locale/crowdin.ts b/locale/crowdin.ts index fee8d729..52c74df6 100644 --- a/locale/crowdin.ts +++ b/locale/crowdin.ts @@ -186,33 +186,33 @@ ArticleView - + Failed to create temporary file. 创建临时文件失败。 - + &Look up "%1" 查找 "%1"(&L) - + Look up "%1" in &New Tab 在新标签页中查找 "%1"(&N) - - + + The referenced resource doesn't exist. 所引用的资源不存在。 - + Failed to auto-open resource file, try opening manually: %1. 自动打开资源文件时失败,请尝试手动打开:%1. - + Look up "%1" in %2 在 %2 中查找 "%1" @@ -232,105 +232,105 @@ 审查元素 - + Look up "%1" in %2 in &New Tab 在 %2 中查找 "%1" 并使用新标签页(&N) - + Open Link in New &Tab 在新标签页中打开链接(&T) - + Open Link in &External Browser 在外部浏览器中打开链接(&E) - + Resource 资源 - + Audio 音频 - + TTS Voice TTS 音频 - + Picture 图片 - + Video 视频: %1 视频 - + Video: %1 视频:%1 - + Definition from dictionary "%1": %2 定义:"%1": %2 - + Definition: %1 定义:%1 - + The referenced audio program doesn't exist. 引用的音频播放程序不存在。 - + Op&en Link 打开链接(&E) - + Save &Bookmark "%1..." 保存为书签(&S)“%1...” - + WARNING: Audio Player: %1 警告:音频播放器:%1 - - - + + + ERROR: %1 错误: %1 - + Save sound 保存音频文件 - + Save image 保存图片 - + Image files (*.bmp *.jpg *.png *.tif);;All files (*.*) 图片文件 (*.bmp *.jpg *.png *.tif);;所有文件 (*.*) - + Save &image... 保存图片(&I)... @@ -345,38 +345,38 @@ 匹配(%1/%2) - + Save s&ound... 保存音频文件(&O)... - + Send "%1" to input line 将 "%1" 发送到输入框 - - + + &Add "%1" to history 将 "%1" 添加到历史(&A) - + &Send Current Article to Anki 发送当前文章到 Anki(&S) - + &Send selected text to Anki 发送选中文本到 Anki(&S) - + Sound files (*.wav *.opus *.ogg *.oga *.mp3 *.mp4 *.aac *.flac *.mid *.wv *.ape *.spx);;All files (*.*) 声音文件 (*.wav *.opus *.ogg *.oga *.mp3 *.mp4 *.aac *.flac *.mid *.wv *.ape *.spx);;所有文件 (*.*) - + Failed to play sound file: %1 播放音频文件失败:%1 @@ -813,11 +813,21 @@ between classic and school orthography in cyrillic) 词条 - + Edit the dictionary via command: %1 编辑词典信息的命令行:%1 + + + Index filename: + + + + + Open index folder + + DictListModel @@ -1457,12 +1467,12 @@ between classic and school orthography in cyrillic) 初始化 GoldenDict-ng - + Please wait... 请稍候... - + Indexing... @@ -2727,17 +2737,17 @@ between classic and school orthography in cyrillic) F4 - + All 全部 - + Back 回退 - + %1 dictionaries, %2 articles, %3 words 词典数:%1,文章数:%2,词条数:%3 @@ -2763,12 +2773,12 @@ between classic and school orthography in cyrillic) - + &Quit 退出(&Q) - + Error 错误 @@ -2783,12 +2793,12 @@ between classic and school orthography in cyrillic) 关闭至系统托盘(&C) - + Can't save article: %1 无法保存文章:%1 - + Zoom In 放大 @@ -2818,7 +2828,7 @@ between classic and school orthography in cyrillic) 保存文章(&S) - + Save Article As 文章另存为 @@ -2848,17 +2858,17 @@ between classic and school orthography in cyrillic) 主页(&H) - + New Release Available 有新版本可用 - + Zoom Out 缩小 - + Show &Main Window 显示主窗口(&M) @@ -2868,27 +2878,27 @@ between classic and school orthography in cyrillic) 关于 GoldenDict-ng - + Download 下载 - + Page Setup 页面设置 - + Normal Size 正常大小 - + Failed to initialize hotkeys monitoring mechanism.<br>Make sure your XServer has RECORD extension turned on. 初始化热键监视机制失败。<br>请确保你的 XServer 已启用 RECORD 扩展。 - + Version <b>%1</b> of GoldenDict is now available for download.<br>Click <b>Download</b> to get to the download page. 有新版 GoldenDict 可用,版本为 <b>%1</b>。<br> 点击<b>下载</b>,打开下载页面。 @@ -2904,12 +2914,12 @@ between classic and school orthography in cyrillic) Ctrl+F5 - + Loading... 加载中…… - + (untitled) (未命名) @@ -2920,12 +2930,12 @@ between classic and school orthography in cyrillic) - + Welcome! 欢迎使用! - + Pronounce Word (Alt+S) 朗读词条(Alt+S) @@ -2935,22 +2945,22 @@ between classic and school orthography in cyrillic) 保存文章 - + Skip This Release 忽略此次升级 - + Forward 前进 - + Print Article 打印文章 - + No printer is available. Please install one first. 找不到可用的打印机,请先安装一个打印机。 @@ -2975,42 +2985,42 @@ between classic and school orthography in cyrillic) 缩放(&Z) - + Words Zoom In 单词列表 - 放大 - + Words Zoom Out 单词列表 - 缩小 - + Words Normal Size 单词列表 - 正常大小 - + Close current tab 关闭当前标签页 - + Close all tabs 关闭所有标签页 - + Close all tabs except current 关闭其它标签页 - + Opened tabs 已打开的标签页 - + New Tab 新建标签页 @@ -3025,65 +3035,65 @@ between classic and school orthography in cyrillic) 配置文件夹(&C) - + &Menubar 菜单栏(&M) - + Found in Dictionaries: 在以下词典中找到: - + Add all tabs to Favorites 将全部标签页添加至收藏 - + WARNING: %1 警告: %1 - + String to search in dictionaries. The wildcards '*', '?' and sets of symbols '[...]' are allowed. To find '*', '?', '[', ']' symbols use '\*', '\?', '\[', '\]' respectively 词典搜索中的字符串:可以使用通配符“*”、“?”和符号分组“[...]”。 如需查找“*”、“?”、“[”和“]”字符,请对应使用“\*”、“\?”、“\[”和“\]” - + Open Tabs List 打开标签页列表 - - - - - + + + + + Remove current tab from Favorites 从收藏中删除当前标签页 - + %1 - %2 %1 - %2 - + You have chosen to hide a menubar. Use %1 to show it back. 你选择了隐藏菜单栏,使用 %1 再次显示。 - + Ctrl+M Ctrl+M - - + + &Show 显示(&S) @@ -3093,37 +3103,37 @@ To find '*', '?', '[', ']' symbols use & 导出(&E) - - + + &Hide 隐藏(&H) - + Export history to file 导出历史记录到文件 - - - + + + Text files (*.txt);;All files (*.*) 文本文件 (*.txt);;所有文件 (*.*) - + History export complete 历史记录导出完成 - - - - - - - - + + + + + + + + Export error: 导出错误: @@ -3138,96 +3148,96 @@ To find '*', '?', '[', ']' symbols use & 导入(&I) - + Import history from file 导入历史文件 - + Import error: invalid data in file 导入失败:无效数据 - + History import complete 历史导入成功 - - - + + + Import error: 导入错误: - + Export Favorites to file 导出收藏记录到文件 - + XML files (*.xml);;All files (*.*) XML 文件 (*.xml);;所有文件 (*.*) - - + + Favorites export complete 收藏导出完成 - + Export Favorites to file as plain list 以纯列表形式导出收藏列表到文件 - + Import Favorites from file 导入收藏文件 - + XML files (*.xml);;Txt files (*.txt);;All files (*.*) XML文件(*.xml);;文本文件(*.txt);;所有文件(*.*) - + Favorites import complete 收藏导入完成 - - + + Data parsing error 数据解析错误 - + Dictionary info 词典信息 - + Dictionary headwords 词典词条 - + Open dictionary folder 打开词典文件夹 - + Edit dictionary 编辑词典信息 - + Now indexing for full-text search: 正在为全文搜索进行索引: - + Remove headword "%1" from Favorites? 从收藏中删除标题字“%1”? @@ -3278,7 +3288,7 @@ To find '*', '?', '[', ']' symbols use & - + Menu Button 菜单按钮 @@ -3329,10 +3339,10 @@ To find '*', '?', '[', ']' symbols use & - - - - + + + + Add current tab to Favorites 将当前标签页添加至收藏 @@ -3347,47 +3357,47 @@ To find '*', '?', '[', ']' symbols use & 导出至列表 - + Show Names in Dictionary &Bar 在词典栏中显示词典名称(&B) - + Show Small Icons in &Toolbars 在工具栏上显示小图标(&T) - + &Navigation 导航栏(&N) - + Enable Scanning 取词弹窗 - + Article, Complete (*.html) 文章, 完整 (*.html) - + Article, HTML Only (*.html) 文章, 仅 HTML (*.html) - + Saving article... 文章保存中…… - + Save article complete - + The main window is set to be always on top. 主窗口已设置为总在最前。 @@ -3397,8 +3407,8 @@ To find '*', '?', '[', ']' symbols use & 历史面板(&H) - - + + Accessibility API is not enabled 无障碍API未启用 @@ -3714,7 +3724,7 @@ for all program's network requests. 仅限右 Ctrl - + Lingvo Lingvo @@ -3745,7 +3755,7 @@ in the pressed state when the word selection changes. 在当前页之后打开新标签页 - + Restart the program to apply the language change. 变更界面语言需要重新启动程序才能生效。 @@ -3805,7 +3815,7 @@ download page. 密码: - + Default 默认 @@ -3815,7 +3825,7 @@ download page. 界面(&I) - + Changing Language 变更界面语言 @@ -4024,16 +4034,6 @@ however, the article from the topmost dictionary is shown. Automatically scroll to target article 自动定位到当前词典 - - - Dictionary Font: - 词典字体: - - - - set the fallback font family for dictionary - 设置词典的备用字体 - Article Display style: @@ -4348,7 +4348,7 @@ from Stardict, Babylon and GLS dictionaries 用 Ctrl-tab 浏览标签页时,以“最近使用”为序 - + Babylon 巴比伦文 @@ -4413,27 +4413,27 @@ from Stardict, Babylon and GLS dictionaries 分钟 - + Classic 经典 - + Modern 现代 - + Lingoes 灵格斯 - + Lingoes-Blue 灵格斯-蓝色调 - + MB MB @@ -4447,6 +4447,41 @@ from Stardict, Babylon and GLS dictionaries Enable index with positional information + + + Standard Font + + + + + Monospace Font + + + + + Serif Font + + + + + Sans-serif Font + + + + + Appearance + + + + + These fonts will be applied when the fonts specified by a dictionary are not found. + + + + + Fallback Fonts + + ProgramTypeEditor @@ -4532,7 +4567,7 @@ from Stardict, Babylon and GLS dictionaries - + Article decoding error 文章解码错误 @@ -4640,22 +4675,22 @@ from Stardict, Babylon and GLS dictionaries ResourceToSaveHandler - + ERROR: %1 错误: %1 - + Resource saving error: 资源保存失败: - + The referenced resource failed to download. 所引用的资源下载失败。 - + WARNING: %1 警告: %1 diff --git a/src/config.cc b/src/config.cc index 4eca0f2b..777dfeea 100644 --- a/src/config.cc +++ b/src/config.cc @@ -296,17 +296,17 @@ Romaji::Romaji(): Group * Class::getGroup( unsigned id ) { - for( int x = 0; x < groups.size(); x++ ) - if( groups.at( x ).id == id ) - return &groups[ x ]; + for ( auto & group : groups ) + if ( group.id == id ) + return &group; return 0; } Group const * Class::getGroup( unsigned id ) const { - for( int x = 0; x < groups.size(); x++ ) - if( groups.at( x ).id == id ) - return &groups.at( x ); + for ( const auto & group : groups ) + if ( group.id == id ) + return &group; return 0; } @@ -437,13 +437,11 @@ MutedDictionaries loadMutedDictionaries( const QDomNode & mutedDictionaries ) void saveMutedDictionaries( QDomDocument & dd, QDomElement & muted, MutedDictionaries const & mutedDictionaries ) { - for( MutedDictionaries::const_iterator i = mutedDictionaries.begin(); - i != mutedDictionaries.end(); ++i ) - { + for ( const auto & mutedDictionarie : mutedDictionaries ) { QDomElement dict = dd.createElement( "mutedDictionary" ); muted.appendChild( dict ); - QDomText value = dd.createTextNode( *i ); + QDomText value = dd.createTextNode( mutedDictionarie ); dict.appendChild( value ); } } @@ -847,8 +845,10 @@ Class load() c.preferences.alwaysOnTop = ( preferences.namedItem( "alwaysOnTop" ).toElement().text() == "1" ); c.preferences.searchInDock = ( preferences.namedItem( "searchInDock" ).toElement().text() == "1" ); - if ( !preferences.namedItem( "webFontFamily" ).isNull() ) - c.preferences.webFontFamily = preferences.namedItem( "webFontFamily" ).toElement().text(); + if ( !preferences.namedItem( "customFonts" ).isNull() ) { + CustomFonts fonts = CustomFonts::fromElement( preferences.namedItem( "customFonts" ).toElement() ); + c.preferences.customFonts = fonts; + } if ( !preferences.namedItem( "doubleClickTranslates" ).isNull() ) c.preferences.doubleClickTranslates = ( preferences.namedItem( "doubleClickTranslates" ).toElement().text() == "1" ); @@ -1195,19 +1195,18 @@ void saveGroup( Group const & data, QDomElement & group ) group.setAttributeNode( shortcut ); } - for( QVector< DictionaryRef >::const_iterator j = data.dictionaries.begin(); j != data.dictionaries.end(); ++j ) - { + for ( const auto & dictionarie : data.dictionaries ) { QDomElement dictionary = dd.createElement( "dictionary" ); group.appendChild( dictionary ); - QDomText value = dd.createTextNode( j->id ); + QDomText value = dd.createTextNode( dictionarie.id ); dictionary.appendChild( value ); QDomAttr name = dd.createAttribute( "name" ); - name.setValue( j->name ); + name.setValue( dictionarie.name ); dictionary.setAttributeNode( name ); } @@ -1215,23 +1214,19 @@ void saveGroup( Group const & data, QDomElement & group ) QDomElement muted = dd.createElement( "mutedDictionaries" ); group.appendChild( muted ); - for( MutedDictionaries::const_iterator i = data.mutedDictionaries.begin(); - i != data.mutedDictionaries.end(); ++i ) - { + for ( const auto & mutedDictionarie : data.mutedDictionaries ) { QDomElement dict = dd.createElement( "mutedDictionary" ); muted.appendChild( dict ); - QDomText value = dd.createTextNode( *i ); + QDomText value = dd.createTextNode( mutedDictionarie ); dict.appendChild( value ); } - for( MutedDictionaries::const_iterator i = data.popupMutedDictionaries.begin(); - i != data.popupMutedDictionaries.end(); ++i ) - { + for ( const auto & popupMutedDictionarie : data.popupMutedDictionaries ) { QDomElement dict = dd.createElement( "popupMutedDictionary" ); muted.appendChild( dict ); - QDomText value = dd.createTextNode( *i ); + QDomText value = dd.createTextNode( popupMutedDictionarie ); dict.appendChild( value ); } } @@ -1254,16 +1249,15 @@ void save( Class const & c ) QDomElement paths = dd.createElement( "paths" ); root.appendChild( paths ); - for( Paths::const_iterator i = c.paths.begin(); i != c.paths.end(); ++i ) - { + for ( const auto & i : c.paths ) { QDomElement path = dd.createElement( "path" ); paths.appendChild( path ); QDomAttr recursive = dd.createAttribute( "recursive" ); - recursive.setValue( i->recursive ? "1" : "0" ); + recursive.setValue( i.recursive ? "1" : "0" ); path.setAttributeNode( recursive ); - QDomText value = dd.createTextNode( i->path ); + QDomText value = dd.createTextNode( i.path ); path.appendChild( value ); } @@ -1273,20 +1267,19 @@ void save( Class const & c ) QDomElement soundDirs = dd.createElement( "sounddirs" ); root.appendChild( soundDirs ); - for( SoundDirs::const_iterator i = c.soundDirs.begin(); i != c.soundDirs.end(); ++i ) - { + for ( const auto & i : c.soundDirs ) { QDomElement soundDir = dd.createElement( "sounddir" ); soundDirs.appendChild( soundDir ); QDomAttr name = dd.createAttribute( "name" ); - name.setValue( i->name ); + name.setValue( i.name ); soundDir.setAttributeNode( name ); QDomAttr icon = dd.createAttribute( "icon" ); - icon.setValue( i->iconFilename ); + icon.setValue( i.iconFilename ); soundDir.setAttributeNode( icon ); - QDomText value = dd.createTextNode( i->path ); + QDomText value = dd.createTextNode( i.path ); soundDir.appendChild( value ); } @@ -1312,12 +1305,11 @@ void save( Class const & c ) nextId.setValue( QString::number( c.groups.nextId ) ); groups.setAttributeNode( nextId ); - for( Groups::const_iterator i = c.groups.begin(); i != c.groups.end(); ++i ) - { + for ( const auto & i : c.groups ) { QDomElement group = dd.createElement( "group" ); groups.appendChild( group ); - saveGroup( *i, group ); + saveGroup( i, group ); } } @@ -1328,10 +1320,9 @@ void save( Class const & c ) hunspell.setAttributeNode( path ); root.appendChild( hunspell ); - for( int x = 0; x < c.hunspell.enabledDictionaries.size(); ++x ) - { + for ( const auto & enabledDictionarie : c.hunspell.enabledDictionaries ) { QDomElement en = dd.createElement( "enabled" ); - QDomText value = dd.createTextNode( c.hunspell.enabledDictionaries.at( x ) ); + QDomText value = dd.createTextNode( enabledDictionarie ); en.appendChild( value ); hunspell.appendChild( en ); @@ -1470,29 +1461,28 @@ void save( Class const & c ) QDomElement mws = dd.createElement( "mediawikis" ); root.appendChild( mws ); - for( MediaWikis::const_iterator i = c.mediawikis.begin(); i != c.mediawikis.end(); ++i ) - { + for ( const auto & mediawiki : c.mediawikis ) { QDomElement mw = dd.createElement( "mediawiki" ); mws.appendChild( mw ); QDomAttr id = dd.createAttribute( "id" ); - id.setValue( i->id ); + id.setValue( mediawiki.id ); mw.setAttributeNode( id ); QDomAttr name = dd.createAttribute( "name" ); - name.setValue( i->name ); + name.setValue( mediawiki.name ); mw.setAttributeNode( name ); QDomAttr url = dd.createAttribute( "url" ); - url.setValue( i->url ); + url.setValue( mediawiki.url ); mw.setAttributeNode( url ); QDomAttr enabled = dd.createAttribute( "enabled" ); - enabled.setValue( i->enabled ? "1" : "0" ); + enabled.setValue( mediawiki.enabled ? "1" : "0" ); mw.setAttributeNode( enabled ); QDomAttr icon = dd.createAttribute( "icon" ); - icon.setValue( i->icon ); + icon.setValue( mediawiki.icon ); mw.setAttributeNode( icon ); } } @@ -1501,33 +1491,32 @@ void save( Class const & c ) QDomElement wss = dd.createElement( "websites" ); root.appendChild( wss ); - for( WebSites::const_iterator i = c.webSites.begin(); i != c.webSites.end(); ++i ) - { + for ( const auto & webSite : c.webSites ) { QDomElement ws = dd.createElement( "website" ); wss.appendChild( ws ); QDomAttr id = dd.createAttribute( "id" ); - id.setValue( i->id ); + id.setValue( webSite.id ); ws.setAttributeNode( id ); QDomAttr name = dd.createAttribute( "name" ); - name.setValue( i->name ); + name.setValue( webSite.name ); ws.setAttributeNode( name ); QDomAttr url = dd.createAttribute( "url" ); - url.setValue( i->url ); + url.setValue( webSite.url ); ws.setAttributeNode( url ); QDomAttr enabled = dd.createAttribute( "enabled" ); - enabled.setValue( i->enabled ? "1" : "0" ); + enabled.setValue( webSite.enabled ? "1" : "0" ); ws.setAttributeNode( enabled ); QDomAttr icon = dd.createAttribute( "icon" ); - icon.setValue( i->iconFilename ); + icon.setValue( webSite.iconFilename ); ws.setAttributeNode( icon ); QDomAttr inside_iframe = dd.createAttribute( "inside_iframe" ); - inside_iframe.setValue( i->inside_iframe ? "1" : "0" ); + inside_iframe.setValue( webSite.inside_iframe ? "1" : "0" ); ws.setAttributeNode( inside_iframe ); } } @@ -1536,37 +1525,36 @@ void save( Class const & c ) QDomElement dss = dd.createElement( "dictservers" ); root.appendChild( dss ); - for( DictServers::const_iterator i = c.dictServers.begin(); i != c.dictServers.end(); ++i ) - { + for ( const auto & dictServer : c.dictServers ) { QDomElement ds = dd.createElement( "server" ); dss.appendChild( ds ); QDomAttr id = dd.createAttribute( "id" ); - id.setValue( i->id ); + id.setValue( dictServer.id ); ds.setAttributeNode( id ); QDomAttr name = dd.createAttribute( "name" ); - name.setValue( i->name ); + name.setValue( dictServer.name ); ds.setAttributeNode( name ); QDomAttr url = dd.createAttribute( "url" ); - url.setValue( i->url ); + url.setValue( dictServer.url ); ds.setAttributeNode( url ); QDomAttr enabled = dd.createAttribute( "enabled" ); - enabled.setValue( i->enabled ? "1" : "0" ); + enabled.setValue( dictServer.enabled ? "1" : "0" ); ds.setAttributeNode( enabled ); QDomAttr databases = dd.createAttribute( "databases" ); - databases.setValue( i->databases ); + databases.setValue( dictServer.databases ); ds.setAttributeNode( databases ); QDomAttr strategies = dd.createAttribute( "strategies" ); - strategies.setValue( i->strategies ); + strategies.setValue( dictServer.strategies ); ds.setAttributeNode( strategies ); QDomAttr icon = dd.createAttribute( "icon" ); - icon.setValue( i->iconFilename ); + icon.setValue( dictServer.iconFilename ); ds.setAttributeNode( icon ); } } @@ -1575,33 +1563,32 @@ void save( Class const & c ) QDomElement programs = dd.createElement( "programs" ); root.appendChild( programs ); - for( Programs::const_iterator i = c.programs.begin(); i != c.programs.end(); ++i ) - { + for ( const auto & program : c.programs ) { QDomElement p = dd.createElement( "program" ); programs.appendChild( p ); QDomAttr id = dd.createAttribute( "id" ); - id.setValue( i->id ); + id.setValue( program.id ); p.setAttributeNode( id ); QDomAttr name = dd.createAttribute( "name" ); - name.setValue( i->name ); + name.setValue( program.name ); p.setAttributeNode( name ); QDomAttr commandLine = dd.createAttribute( "commandLine" ); - commandLine.setValue( i->commandLine ); + commandLine.setValue( program.commandLine ); p.setAttributeNode( commandLine ); QDomAttr enabled = dd.createAttribute( "enabled" ); - enabled.setValue( i->enabled ? "1" : "0" ); + enabled.setValue( program.enabled ? "1" : "0" ); p.setAttributeNode( enabled ); QDomAttr type = dd.createAttribute( "type" ); - type.setValue( QString::number( i->type ) ); + type.setValue( QString::number( program.type ) ); p.setAttributeNode( type ); QDomAttr icon = dd.createAttribute( "icon" ); - icon.setValue( i->iconFilename ); + icon.setValue( program.iconFilename ); p.setAttributeNode( icon ); } } @@ -1668,9 +1655,9 @@ void save( Class const & c ) opt.appendChild( dd.createTextNode( c.preferences.interfaceLanguage ) ); preferences.appendChild( opt ); - opt = dd.createElement( "webFontFamily" ); - opt.appendChild( dd.createTextNode( c.preferences.webFontFamily ) ); - preferences.appendChild( opt ); + opt = dd.createElement( "customFonts" ); + auto customFont = c.preferences.customFonts.toElement( dd ); + preferences.appendChild( customFont ); opt = dd.createElement( "displayStyle" ); opt.appendChild( dd.createTextNode( c.preferences.displayStyle ) ); diff --git a/src/config.hh b/src/config.hh index 04a8f26c..c839d10b 100644 --- a/src/config.hh +++ b/src/config.hh @@ -13,6 +13,7 @@ #include #include #include "ex.hh" +#include #include #include @@ -189,6 +190,56 @@ struct FullTextSearch {} }; +struct CustomFonts +{ + QString standard; + QString serif; + QString sansSerif; + QString monospace; + + bool operator==( CustomFonts const & other ) const + { + return standard == other.standard && serif == other.serif && sansSerif == other.sansSerif + && monospace == other.monospace; + } + + bool operator!=( CustomFonts const & other ) const + { + return !operator==( other ); + } + + QDomElement toElement( QDomDocument dd ) const + { + QDomElement proxy = dd.createElement( "customFonts" ); + + QDomAttr standard_attr = dd.createAttribute( "standard" ); + standard_attr.setValue( this->standard ); + proxy.setAttributeNode( standard_attr ); + + QDomAttr serif_attr = dd.createAttribute( "serif" ); + serif_attr.setValue( this->serif ); + proxy.setAttributeNode( serif_attr ); + + QDomAttr sans_attr = dd.createAttribute( "sans-serif" ); + sans_attr.setValue( this->sansSerif ); + proxy.setAttributeNode( sans_attr ); + QDomAttr mono_attr = dd.createAttribute( "monospace" ); + mono_attr.setValue( this->monospace ); + proxy.setAttributeNode( mono_attr ); + return proxy; + } + + static CustomFonts fromElement( QDomElement proxy ) + { + CustomFonts c; + c.standard = proxy.attribute( "standard" ); + c.serif = proxy.attribute( "serif" ); + c.sansSerif = proxy.attribute( "sans-serif" ); + c.monospace = proxy.attribute( "monospace" ); + return c; + } +}; + /// This class encapsulates supported backend preprocessor logic, /// discourages duplicating backend names in code, which is error-prone. class InternalPlayerBackend @@ -257,7 +308,7 @@ struct Preferences { QString interfaceLanguage; // Empty value corresponds to system default QString displayStyle; // Empty value corresponds to the default one - QString webFontFamily; // Empty value corresponds to the default one + CustomFonts customFonts; bool newTabsOpenAfterCurrentOne; bool newTabsOpenInBackground; bool hideSingleTab; diff --git a/src/ui/mainwindow.cc b/src/ui/mainwindow.cc index 1aade01a..968e2cd5 100644 --- a/src/ui/mainwindow.cc +++ b/src/ui/mainwindow.cc @@ -98,12 +98,36 @@ QString ApplicationSettingName = "GoldenDict"; void MainWindow::changeWebEngineViewFont() const { - if ( cfg.preferences.webFontFamily.isEmpty() ) { + if ( cfg.preferences.customFonts.standard.isEmpty() ) { QWebEngineProfile::defaultProfile()->settings()->resetFontFamily( QWebEngineSettings::StandardFont ); } else { QWebEngineProfile::defaultProfile()->settings()->setFontFamily( QWebEngineSettings::StandardFont, - cfg.preferences.webFontFamily ); + cfg.preferences.customFonts.standard ); + } + + if ( cfg.preferences.customFonts.serif.isEmpty() ) { + QWebEngineProfile::defaultProfile()->settings()->resetFontFamily( QWebEngineSettings::SerifFont ); + } + else { + QWebEngineProfile::defaultProfile()->settings()->setFontFamily( QWebEngineSettings::SerifFont, + cfg.preferences.customFonts.serif ); + } + + if ( cfg.preferences.customFonts.sansSerif.isEmpty() ) { + QWebEngineProfile::defaultProfile()->settings()->resetFontFamily( QWebEngineSettings::SansSerifFont ); + } + else { + QWebEngineProfile::defaultProfile()->settings()->setFontFamily( QWebEngineSettings::SansSerifFont, + cfg.preferences.customFonts.sansSerif ); + } + + if ( cfg.preferences.customFonts.monospace.isEmpty() ) { + QWebEngineProfile::defaultProfile()->settings()->resetFontFamily( QWebEngineSettings::FixedFont ); + } + else { + QWebEngineProfile::defaultProfile()->settings()->setFontFamily( QWebEngineSettings::FixedFont, + cfg.preferences.customFonts.monospace ); } } diff --git a/src/ui/preferences.cc b/src/ui/preferences.cc index da5e328b..3c399df2 100644 --- a/src/ui/preferences.cc +++ b/src/ui/preferences.cc @@ -97,12 +97,34 @@ Preferences::Preferences( QWidget * parent, Config::Class & cfg_ ): } } - prevWebFontFamily = p.webFontFamily; + prevWebFontFamily = p.customFonts; - if(!p.webFontFamily.isEmpty()) - ui.fontFamilies->setCurrentText( p.webFontFamily ); + if ( !p.customFonts.standard.isEmpty() ) + ui.font_standard->setCurrentText( p.customFonts.standard ); else { - ui.fontFamilies->setCurrentFont( QApplication::font() ); + ui.font_standard->setCurrentFont( + QWebEngineProfile::defaultProfile()->settings()->fontFamily( QWebEngineSettings::StandardFont ) ); + } + + if ( !p.customFonts.serif.isEmpty() ) + ui.font_serif->setCurrentText( p.customFonts.serif ); + else { + ui.font_serif->setCurrentFont( + QWebEngineProfile::defaultProfile()->settings()->fontFamily( QWebEngineSettings::SerifFont ) ); + } + + if ( !p.customFonts.sansSerif.isEmpty() ) + ui.font_sans->setCurrentText( p.customFonts.sansSerif ); + else { + ui.font_sans->setCurrentFont( + QWebEngineProfile::defaultProfile()->settings()->fontFamily( QWebEngineSettings::SansSerifFont ) ); + } + + if ( !p.customFonts.monospace.isEmpty() ) + ui.font_monospace->setCurrentText( p.customFonts.monospace ); + else { + ui.font_monospace->setCurrentFont( + QWebEngineProfile::defaultProfile()->settings()->fontFamily( QWebEngineSettings::FixedFont ) ); } ui.displayStyle->addItem( QIcon( ":/icons/programicon_old.png" ), tr( "Default" ), QString() ); @@ -354,11 +376,13 @@ Config::Preferences Preferences::getPreferences() ui.interfaceLanguage->itemData( ui.interfaceLanguage->currentIndex() ).toString(); - //bypass the first default - if(ui.fontFamilies->currentIndex()>0) - p.webFontFamily = ui.fontFamilies->currentText(); - else - p.webFontFamily = ""; + Config::CustomFonts c; + c.standard = ui.font_standard->currentText(); + c.serif = ui.font_serif->currentText(); + c.sansSerif = ui.font_sans->currentText(); + c.monospace = ui.font_monospace->currentText(); + p.customFonts = c; + p.displayStyle = ui.displayStyle->itemData( @@ -560,19 +584,16 @@ void Preferences::on_buttonBox_accepted() QMessageBox::information( this, tr( "Changing Language" ), tr( "Restart the program to apply the language change." ) ); - auto currentFontFamily = ui.fontFamilies->currentFont().family(); - if( prevWebFontFamily != currentFontFamily ) - { - //reset to default font . - if( currentFontFamily.isEmpty() ) - { - QWebEngineProfile::defaultProfile()->settings()->resetFontFamily( QWebEngineSettings::StandardFont ); - } - else - { - QWebEngineProfile::defaultProfile()->settings()->setFontFamily( QWebEngineSettings::StandardFont, - currentFontFamily ); - } + auto c = getPreferences(); + if ( c.customFonts != prevWebFontFamily ) { + QWebEngineProfile::defaultProfile()->settings()->setFontFamily( QWebEngineSettings::StandardFont, + c.customFonts.standard ); + QWebEngineProfile::defaultProfile()->settings()->setFontFamily( QWebEngineSettings::SerifFont, + c.customFonts.serif ); + QWebEngineProfile::defaultProfile()->settings()->setFontFamily( QWebEngineSettings::SansSerifFont, + c.customFonts.sansSerif ); + QWebEngineProfile::defaultProfile()->settings()->setFontFamily( QWebEngineSettings::FixedFont, + c.customFonts.monospace ); } } @@ -602,3 +623,4 @@ void Preferences::on_limitInputPhraseLength_toggled( bool checked ) { ui.inputPhraseLengthLimit->setEnabled( checked ); } + diff --git a/src/ui/preferences.hh b/src/ui/preferences.hh index d7c1f466..e4ebbd4c 100644 --- a/src/ui/preferences.hh +++ b/src/ui/preferences.hh @@ -13,7 +13,7 @@ class Preferences: public QDialog int prevInterfaceLanguage = 0; - QString prevWebFontFamily; + Config::CustomFonts prevWebFontFamily; Config::Class & cfg; QAction helpAction; @@ -55,8 +55,6 @@ private slots: void on_collapseBigArticles_toggled( bool checked ); void on_limitInputPhraseLength_toggled( bool checked ); - - }; #endif diff --git a/src/ui/preferences.ui b/src/ui/preferences.ui index 91ba2587..947881bc 100644 --- a/src/ui/preferences.ui +++ b/src/ui/preferences.ui @@ -6,7 +6,7 @@ 0 0 - 787 + 788 730 @@ -53,229 +53,6 @@ 9 - - - - When enabled, an icon appears in the system tray area which can be used -to open main window and perform other tasks. - - - Enable system tray icon - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - false - - - true - - - false - - - - - - With this on, the application starts directly to system tray without showing -its main window. - - - Start to system tray - - - - - - - With this on, an attempt to close main window would hide it instead of closing -the application. - - - Close to system tray - - - - - - - - - - Normally, pressing ESC key moves focus to the translation line. -With this on however, it will hide the main window. - - - ESC key hides main window - - - - - - - Normally, clicking on a link, double-clicking on a word or looking up -selection in an article loads the translation and almost immediately -scrolls to the article from the same dictionary. With this option off, -however, the article from the topmost dictionary is shown. - - - Automatically scroll to target article - - - true - - - - - - - - - - 0 - 0 - - - - Adjust this value to avoid huge context menus. - - - Context menu dictionaries limit: - - - - - - - - 0 - 0 - - - - 9999 - - - 20 - - - - - - - - 0 - 0 - - - - - - - - - - - - - Startup - - - - - - Automatically starts GoldenDict after operation system bootup. - - - Start with system - - - - - - - - - - Interface language: - - - - - - - Dictionary Font: - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - Turn the UI to dark. - - - Dark Mode - - - - - - - Turn the article display style to dark. - - - Dark Reader Mode - - - - - - - - - Turn this option on if you want to select words by single mouse click - - - Select word by single click - - - - - - - QComboBox::AdjustToContents - - - - - - - - 0 - 0 - - - - set the fallback font family for dictionary - - - @@ -336,30 +113,380 @@ be the last ones. - - + + + + Normally, pressing ESC key moves focus to the translation line. +With this on however, it will hide the main window. + + + ESC key hides main window + + + + + + + Turn this option on if you want to select words by single mouse click + + + Select word by single click + + + + + + + Startup + + + + + + Automatically starts GoldenDict after operation system bootup. + + + Start with system + + + + + + + + + + Normally, clicking on a link, double-clicking on a word or looking up +selection in an article loads the translation and almost immediately +scrolls to the article from the same dictionary. With this option off, +however, the article from the topmost dictionary is shown. + + + Automatically scroll to target article + + + true + + + + + + + When enabled, an icon appears in the system tray area which can be used +to open main window and perform other tasks. + + + Enable system tray icon + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + false + + + true + + + false + + + + + + With this on, the application starts directly to system tray without showing +its main window. + + + Start to system tray + + + + + + + With this on, an attempt to close main window would hide it instead of closing +the application. + + + Close to system tray + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + - + + + + 0 + 0 + + + + Adjust this value to avoid huge context menus. + - Article Display style: + Context menu dictionaries limit: - - - - - - Add-on style: + + + + 0 + 0 + + + + 9999 + + + 20 - + + + + 0 + 0 + + + + + + + + + + Appearance + + + + + + + + Interface language: + + + + + + + + 0 + 0 + + + + + 153 + 0 + + + + QComboBox::AdjustToContents + + + + + + + + + + + Article Display style: + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + + + + + + + + Add-on style: + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + + + + + + Turn the UI to dark. + + + Dark Mode + + + + + + + Turn the article display style to dark. + + + Dark Reader Mode + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + These fonts will be applied when the fonts specified by a dictionary are not found. + + + Fallback Fonts + + + + + + Standard Font + + + + + + + + 0 + 0 + + + + + + + + Serif Font + + + + + + + + 0 + 0 + + + + + + + + Sans-serif Font + + + + + + + + 0 + 0 + + + + + + + + Monospace Font + + + + + + + + 0 + 0 + + + + QFontComboBox::MonospacedFonts + + + + + +