feat: v0.6.0 —— 选中语言(中/英)即时切换,导出不再有预览窗口
导出 - 去掉导出预览对话框:Ctrl+E 直接弹保存对话框,选路径即导出 - 导出失败才弹提示,成功只在状态栏显示一行 多语言 - 新增 LanguageManager:中文(zh_CN)/ 英文(en),视图 → 语言 切换, 立即生效并记住选择 - 英文翻译由 translations/voiletmark_en.ts(69 条)编译成 .qm 内嵌 - 打包 Qt 官方的 qtbase_zh_CN.qm,文件对话框 / 消息框的按钮也跟着变中文 - 欢迎文档随语言切换(新增英文版) - retranslateUi 负责菜单、动作、状态栏、侧栏文案的即时刷新 其它 - 删除 ExportDialog 与对应截图,README 同步
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
一个轻量的跨平台 Markdown 编辑器,基于 **Qt 5 / C++17** 构建。
|
||||
|
||||
当前版本 **0.5.1**。
|
||||
当前版本 **0.6.0**。
|
||||
|
||||
## 界面
|
||||
|
||||
@@ -14,10 +14,6 @@
|
||||
|
||||

|
||||
|
||||
导出 PDF 前先给一个预览窗口,确认无误再选路径保存:
|
||||
|
||||

|
||||
|
||||
## 功能
|
||||
|
||||
### 编辑
|
||||
@@ -62,14 +58,22 @@
|
||||
|
||||
### 导出 PDF
|
||||
|
||||
**文件 → 导出 PDF…**(`Ctrl+E`)会先弹出预览窗口,里面就是最终排版;
|
||||
点「保存 PDF…」选个位置即可。A4 纸、16mm 页边距,预览和导出用的是同一份
|
||||
排版文档,所见即所得。
|
||||
**文件 → 导出 PDF…**(`Ctrl+E`)直接弹保存对话框,选个位置就导出,没有中间预览。
|
||||
A4 纸、16mm 页边距。
|
||||
|
||||
导出用的是 Qt 自带的 `QPrinter` + `QTextDocument`,不需要额外的 PDF 库。
|
||||
支持标题、列表(含任务列表)、引用、代码块、行内代码、粗体 / 斜体 / 删除线、
|
||||
链接;图片只输出 alt 文字,表格暂时按原文输出。
|
||||
|
||||
### 语言
|
||||
|
||||
界面支持中文和英文,在 **视图 → 语言** 里切换,立即生效、不需要重启。
|
||||
选择会被记住。
|
||||
|
||||
- 界面文案的中文就是源码本身;英文由 `translations/voiletmark_en.ts` 提供
|
||||
- Qt 自带的对话框(文件选择、消息框按钮)也会跟着切换,
|
||||
中文用的是 Qt 官方的翻译文件
|
||||
|
||||
### 文件
|
||||
|
||||
- 新建、打开、保存、另存为、最近打开(最多 8 条)
|
||||
@@ -169,7 +173,7 @@ VoiletMark --screenshot a.png # 渲染窗口截图后退出(调试 / 视觉
|
||||
| `Ctrl+N` / `Ctrl+O` / `Ctrl+S` | 新建 / 打开 / 保存 |
|
||||
| `Ctrl+Shift+S` | 另存为 |
|
||||
| `Ctrl+Shift+O` | 打开文件夹 |
|
||||
| `Ctrl+E` | 导出 PDF(先预览) |
|
||||
| `Ctrl+E` | 导出 PDF |
|
||||
| `Ctrl+B` | 显示 / 隐藏侧栏 |
|
||||
| `Ctrl+Shift+M` | 源代码模式 |
|
||||
| `Ctrl+1` ~ `Ctrl+6` | 设为 1–6 级标题(再按取消) |
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
TEMPLATE = app
|
||||
TARGET = VoiletMark
|
||||
VERSION = 0.5.1
|
||||
VERSION = 0.6.0
|
||||
|
||||
QT += core gui widgets printsupport
|
||||
|
||||
@@ -23,7 +23,7 @@ SOURCES += \
|
||||
src/MarkdownEditor.cpp \
|
||||
src/MarkdownHighlighter.cpp \
|
||||
src/MarkdownRenderer.cpp \
|
||||
src/ExportDialog.cpp \
|
||||
src/LanguageManager.cpp \
|
||||
src/ThemeManager.cpp
|
||||
|
||||
HEADERS += \
|
||||
@@ -31,7 +31,7 @@ HEADERS += \
|
||||
src/MarkdownEditor.h \
|
||||
src/MarkdownHighlighter.h \
|
||||
src/MarkdownRenderer.h \
|
||||
src/ExportDialog.h \
|
||||
src/LanguageManager.h \
|
||||
src/ThemeManager.h
|
||||
|
||||
# Linux 桌面集成:make install 之后能在应用菜单里找到
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 87 KiB |
@@ -1,5 +1,7 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>packaging/voiletmark.png</file>
|
||||
<file>translations/voiletmark_en.qm</file>
|
||||
<file>translations/qtbase_zh_CN.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
#include "ExportDialog.h"
|
||||
|
||||
#include "MarkdownRenderer.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QFileInfo>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPageSize>
|
||||
#include <QPrinter>
|
||||
#include <QPushButton>
|
||||
#include <QScreen>
|
||||
#include <QTextBrowser>
|
||||
#include <QTextDocument>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
ExportDialog::ExportDialog(const QString &markdown, const QString &documentName,
|
||||
const QString &startDirectory, QWidget *parent)
|
||||
: QDialog(parent)
|
||||
, m_documentName(documentName)
|
||||
, m_startDirectory(startDirectory)
|
||||
{
|
||||
setWindowTitle(tr("导出 PDF — %1")
|
||||
.arg(documentName.isEmpty() ? tr("未命名") : documentName));
|
||||
|
||||
// 别让窗口比屏幕还高,否则底部的按钮会顶到屏幕外面去。
|
||||
const QRect available = screen() ? screen()->availableGeometry() : QRect(0, 0, 1280, 900);
|
||||
resize(qMin(900, available.width() - 80), qMin(860, available.height() - 100));
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(16, 16, 16, 12);
|
||||
layout->setSpacing(10);
|
||||
|
||||
m_document = new QTextDocument(this);
|
||||
MarkdownRenderer::render(markdown, m_document);
|
||||
// A4 去掉 16mm 页边距后的正文宽度(96dpi 下的像素):
|
||||
// 预览和打印用同一个页宽,看到的就是导出的样子。
|
||||
m_document->setPageSize(QSizeF(672.76, 1001.57));
|
||||
|
||||
m_preview = new QTextBrowser(this);
|
||||
m_preview->setFrameShape(QFrame::NoFrame);
|
||||
m_preview->setOpenExternalLinks(true);
|
||||
m_preview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
m_preview->setFixedWidth(700);
|
||||
m_preview->setDocument(m_document);
|
||||
m_preview->setStyleSheet(QStringLiteral(
|
||||
"QTextBrowser { background: #ffffff; color: #1f2328;"
|
||||
" border: 1px solid #d8dde3; border-radius: 4px; }"));
|
||||
|
||||
QHBoxLayout *center = new QHBoxLayout;
|
||||
center->addStretch(1);
|
||||
center->addWidget(m_preview);
|
||||
center->addStretch(1);
|
||||
layout->addLayout(center, 1);
|
||||
|
||||
QLabel *hint = new QLabel(tr("A4 纸、16mm 页边距,内容和预览一致。"), this);
|
||||
hint->setForegroundRole(QPalette::PlaceholderText);
|
||||
|
||||
QPushButton *saveButton = new QPushButton(tr("保存 PDF…"), this);
|
||||
saveButton->setDefault(true);
|
||||
QPushButton *closeButton = new QPushButton(tr("关闭"), this);
|
||||
|
||||
QHBoxLayout *buttons = new QHBoxLayout;
|
||||
buttons->addWidget(hint);
|
||||
buttons->addStretch(1);
|
||||
buttons->addWidget(closeButton);
|
||||
buttons->addWidget(saveButton);
|
||||
layout->addLayout(buttons);
|
||||
|
||||
connect(closeButton, &QPushButton::clicked, this, &QDialog::reject);
|
||||
connect(saveButton, &QPushButton::clicked, this, &ExportDialog::savePdf);
|
||||
}
|
||||
|
||||
void ExportDialog::savePdf()
|
||||
{
|
||||
QString suggested = m_documentName.isEmpty()
|
||||
? tr("未命名")
|
||||
: QFileInfo(m_documentName).completeBaseName();
|
||||
suggested += QStringLiteral(".pdf");
|
||||
|
||||
QString target = QFileDialog::getSaveFileName(
|
||||
this, tr("保存 PDF"), QDir(m_startDirectory).filePath(suggested),
|
||||
tr("PDF 文件 (*.pdf)"));
|
||||
if (target.isEmpty())
|
||||
return;
|
||||
|
||||
if (!target.endsWith(QStringLiteral(".pdf"), Qt::CaseInsensitive))
|
||||
target += QStringLiteral(".pdf");
|
||||
|
||||
QPrinter printer(QPrinter::HighResolution);
|
||||
printer.setOutputFormat(QPrinter::PdfFormat);
|
||||
printer.setOutputFileName(target);
|
||||
printer.setPageSize(QPageSize(QPageSize::A4));
|
||||
printer.setPageMargins(QMarginsF(16, 16, 16, 16), QPageLayout::Millimeter);
|
||||
printer.setDocName(QFileInfo(target).completeBaseName());
|
||||
|
||||
m_document->print(&printer);
|
||||
|
||||
if (!QFileInfo::exists(target) || QFileInfo(target).size() <= 0) {
|
||||
QMessageBox::warning(this, tr("导出失败"),
|
||||
tr("没能写出「%1」,换个位置再试一次。")
|
||||
.arg(QDir::toNativeSeparators(target)));
|
||||
return;
|
||||
}
|
||||
|
||||
QMessageBox::information(this, tr("导出完成"),
|
||||
tr("已保存到\n%1").arg(QDir::toNativeSeparators(target)));
|
||||
accept();
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class QTextBrowser;
|
||||
class QTextDocument;
|
||||
|
||||
/// “导出 PDF”窗口:上方是排版后的预览,下方保存为 PDF。
|
||||
class ExportDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ExportDialog(const QString &markdown, const QString &documentName,
|
||||
const QString &startDirectory, QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
void savePdf();
|
||||
|
||||
QTextBrowser *m_preview = nullptr;
|
||||
QTextDocument *m_document = nullptr;
|
||||
QString m_documentName;
|
||||
QString m_startDirectory;
|
||||
};
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "LanguageManager.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QLocale>
|
||||
#include <QSettings>
|
||||
#include <QTranslator>
|
||||
|
||||
LanguageManager *LanguageManager::instance()
|
||||
{
|
||||
static LanguageManager *manager = new LanguageManager();
|
||||
return manager;
|
||||
}
|
||||
|
||||
LanguageManager::LanguageManager(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
QStringList LanguageManager::availableLanguages()
|
||||
{
|
||||
return {QStringLiteral("zh_CN"), QStringLiteral("en")};
|
||||
}
|
||||
|
||||
QString LanguageManager::displayName(const QString &code)
|
||||
{
|
||||
if (code == QLatin1String("en"))
|
||||
return QStringLiteral("English");
|
||||
return QStringLiteral("中文");
|
||||
}
|
||||
|
||||
void LanguageManager::initialize()
|
||||
{
|
||||
QSettings settings;
|
||||
QString code = settings.value(QStringLiteral("ui/language")).toString();
|
||||
if (!availableLanguages().contains(code)) {
|
||||
code = QLocale::system().language() == QLocale::English
|
||||
? QStringLiteral("en")
|
||||
: QStringLiteral("zh_CN");
|
||||
}
|
||||
setLanguage(code);
|
||||
}
|
||||
|
||||
void LanguageManager::setLanguage(const QString &code)
|
||||
{
|
||||
const QString normalized =
|
||||
(code == QLatin1String("en")) ? QStringLiteral("en") : QStringLiteral("zh_CN");
|
||||
|
||||
if (m_appTranslator) {
|
||||
QCoreApplication::removeTranslator(m_appTranslator);
|
||||
delete m_appTranslator;
|
||||
m_appTranslator = nullptr;
|
||||
}
|
||||
if (m_qtTranslator) {
|
||||
QCoreApplication::removeTranslator(m_qtTranslator);
|
||||
delete m_qtTranslator;
|
||||
m_qtTranslator = nullptr;
|
||||
}
|
||||
|
||||
if (normalized == QLatin1String("en")) {
|
||||
// 源码文案是中文,英文需要一份中文 → 英文的翻译。
|
||||
auto *translator = new QTranslator(this);
|
||||
if (translator->load(QStringLiteral(":/translations/voiletmark_en.qm"))) {
|
||||
QCoreApplication::installTranslator(translator);
|
||||
m_appTranslator = translator;
|
||||
} else {
|
||||
delete translator;
|
||||
}
|
||||
} else {
|
||||
// 中文界面只需要把 Qt 自带的文件对话框 / 消息框也切过来。
|
||||
auto *translator = new QTranslator(this);
|
||||
if (translator->load(QStringLiteral(":/translations/qtbase_zh_CN.qm"))) {
|
||||
QCoreApplication::installTranslator(translator);
|
||||
m_qtTranslator = translator;
|
||||
} else {
|
||||
delete translator;
|
||||
}
|
||||
}
|
||||
|
||||
m_language = normalized;
|
||||
QSettings().setValue(QStringLiteral("ui/language"), m_language);
|
||||
emit languageChanged();
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QTranslator;
|
||||
|
||||
/// 界面语言管理:目前只支持中文(zh_CN)和英文(en)。
|
||||
///
|
||||
/// 源码里的界面文案是中文,所以中文不需要额外的翻译文件,
|
||||
/// 只要把 Qt 自带对话框(文件选择、消息框按钮等)切到中文;
|
||||
/// 英文则加载一份中文 → 英文的翻译文件。
|
||||
class LanguageManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
static LanguageManager *instance();
|
||||
|
||||
/// 读取设置(首次按系统语言猜一个)并应用。
|
||||
void initialize();
|
||||
|
||||
void setLanguage(const QString &code);
|
||||
QString language() const { return m_language; }
|
||||
|
||||
static QStringList availableLanguages();
|
||||
static QString displayName(const QString &code);
|
||||
|
||||
signals:
|
||||
void languageChanged();
|
||||
|
||||
private:
|
||||
explicit LanguageManager(QObject *parent = nullptr);
|
||||
|
||||
QString m_language = QStringLiteral("zh_CN");
|
||||
QTranslator *m_appTranslator = nullptr;
|
||||
QTranslator *m_qtTranslator = nullptr;
|
||||
};
|
||||
+216
-42
@@ -1,7 +1,8 @@
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include "ExportDialog.h"
|
||||
#include "LanguageManager.h"
|
||||
#include "MarkdownEditor.h"
|
||||
#include "MarkdownRenderer.h"
|
||||
#include "ThemeManager.h"
|
||||
|
||||
#include <QAction>
|
||||
@@ -21,7 +22,10 @@
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QPageLayout>
|
||||
#include <QPageSize>
|
||||
#include <QPixmap>
|
||||
#include <QPrinter>
|
||||
#include <QSaveFile>
|
||||
#include <QSettings>
|
||||
#include <QSignalBlocker>
|
||||
@@ -83,6 +87,49 @@ int main()
|
||||
---
|
||||
)VOILETMARK";
|
||||
|
||||
const char kWelcomeTextEn[] = R"VOILETMARK(
|
||||
# Welcome to VoiletMark
|
||||
|
||||
A lightweight cross-platform Markdown editor built with **Qt 5** and C++.
|
||||
|
||||
## Quick start
|
||||
|
||||
- `Ctrl+O` opens a file, `Ctrl+S` saves, `Ctrl+Shift+S` saves as
|
||||
- Drag a Markdown file into the window to open it
|
||||
- `Ctrl+1` – `Ctrl+6` set heading levels, `Ctrl+/` wraps a code block
|
||||
- `Ctrl+E` exports the document to PDF (A4)
|
||||
|
||||
## Modes
|
||||
|
||||
The default view is the editor: Markdown markers are hidden, headings are sized,
|
||||
and the line under the cursor reveals its raw markers.
|
||||
Click `<src>` in the status bar to see the source with line numbers.
|
||||
|
||||
## Theme
|
||||
|
||||
Follows the system light / dark setting by default;
|
||||
switch it under **View → Theme**.
|
||||
|
||||
> Quotes, lists, `inline code`, **bold**, *italic*, ~~strikethrough~~
|
||||
> and [links](https://example.com) all render in place.
|
||||
|
||||
- [x] Syntax highlighting
|
||||
- [x] Folder sidebar
|
||||
- [x] PDF export
|
||||
|
||||
```cpp
|
||||
#include <cstdio>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::printf("Hello, VoiletMark!\n");
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
)VOILETMARK";
|
||||
|
||||
} // namespace
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
@@ -109,6 +156,8 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
this, &MainWindow::changeZoom);
|
||||
connect(m_editor, &MarkdownEditor::fileDropped,
|
||||
this, &MainWindow::openPath);
|
||||
connect(LanguageManager::instance(), &LanguageManager::languageChanged,
|
||||
this, &MainWindow::retranslateUi);
|
||||
|
||||
showWelcomeDocument();
|
||||
updateEditActionStates();
|
||||
@@ -266,40 +315,40 @@ void MainWindow::createSidebar()
|
||||
|
||||
void MainWindow::createMenus()
|
||||
{
|
||||
QMenu *fileMenu = menuBar()->addMenu(tr("文件"));
|
||||
fileMenu->addAction(m_newAction);
|
||||
fileMenu->addAction(m_openAction);
|
||||
fileMenu->addAction(m_openFolderAction);
|
||||
m_recentMenu = fileMenu->addMenu(tr("最近打开"));
|
||||
fileMenu->addSeparator();
|
||||
fileMenu->addAction(m_saveAction);
|
||||
fileMenu->addAction(m_saveAsAction);
|
||||
fileMenu->addAction(m_exportPdfAction);
|
||||
fileMenu->addSeparator();
|
||||
fileMenu->addAction(m_quitAction);
|
||||
m_fileMenu = menuBar()->addMenu(tr("文件"));
|
||||
m_fileMenu->addAction(m_newAction);
|
||||
m_fileMenu->addAction(m_openAction);
|
||||
m_fileMenu->addAction(m_openFolderAction);
|
||||
m_recentMenu = m_fileMenu->addMenu(tr("最近打开"));
|
||||
m_fileMenu->addSeparator();
|
||||
m_fileMenu->addAction(m_saveAction);
|
||||
m_fileMenu->addAction(m_saveAsAction);
|
||||
m_fileMenu->addAction(m_exportPdfAction);
|
||||
m_fileMenu->addSeparator();
|
||||
m_fileMenu->addAction(m_quitAction);
|
||||
|
||||
QMenu *editMenu = menuBar()->addMenu(tr("编辑"));
|
||||
editMenu->addAction(m_undoAction);
|
||||
editMenu->addAction(m_redoAction);
|
||||
editMenu->addSeparator();
|
||||
editMenu->addAction(m_cutAction);
|
||||
editMenu->addAction(m_copyAction);
|
||||
editMenu->addAction(m_pasteAction);
|
||||
editMenu->addSeparator();
|
||||
editMenu->addAction(m_selectAllAction);
|
||||
m_editMenu = menuBar()->addMenu(tr("编辑"));
|
||||
m_editMenu->addAction(m_undoAction);
|
||||
m_editMenu->addAction(m_redoAction);
|
||||
m_editMenu->addSeparator();
|
||||
m_editMenu->addAction(m_cutAction);
|
||||
m_editMenu->addAction(m_copyAction);
|
||||
m_editMenu->addAction(m_pasteAction);
|
||||
m_editMenu->addSeparator();
|
||||
m_editMenu->addAction(m_selectAllAction);
|
||||
|
||||
QMenu *viewMenu = menuBar()->addMenu(tr("视图"));
|
||||
viewMenu->addAction(m_sidebarAction);
|
||||
viewMenu->addAction(m_sourceModeAction);
|
||||
viewMenu->addSeparator();
|
||||
viewMenu->addAction(m_wrapAction);
|
||||
viewMenu->addSeparator();
|
||||
viewMenu->addAction(m_zoomInAction);
|
||||
viewMenu->addAction(m_zoomOutAction);
|
||||
viewMenu->addAction(m_zoomResetAction);
|
||||
viewMenu->addSeparator();
|
||||
m_viewMenu = menuBar()->addMenu(tr("视图"));
|
||||
m_viewMenu->addAction(m_sidebarAction);
|
||||
m_viewMenu->addAction(m_sourceModeAction);
|
||||
m_viewMenu->addSeparator();
|
||||
m_viewMenu->addAction(m_wrapAction);
|
||||
m_viewMenu->addSeparator();
|
||||
m_viewMenu->addAction(m_zoomInAction);
|
||||
m_viewMenu->addAction(m_zoomOutAction);
|
||||
m_viewMenu->addAction(m_zoomResetAction);
|
||||
m_viewMenu->addSeparator();
|
||||
|
||||
QMenu *themeMenu = viewMenu->addMenu(tr("主题"));
|
||||
m_themeMenu = m_viewMenu->addMenu(tr("主题"));
|
||||
QActionGroup *themeGroup = new QActionGroup(this);
|
||||
themeGroup->setExclusive(true);
|
||||
|
||||
@@ -312,7 +361,7 @@ void MainWindow::createMenus()
|
||||
m_themeScheduleAction}) {
|
||||
action->setCheckable(true);
|
||||
themeGroup->addAction(action);
|
||||
themeMenu->addAction(action);
|
||||
m_themeMenu->addAction(action);
|
||||
}
|
||||
m_themeSystemAction->setChecked(true);
|
||||
|
||||
@@ -325,16 +374,33 @@ void MainWindow::createMenus()
|
||||
connect(m_themeScheduleAction, &QAction::triggered, this,
|
||||
[this] { applyThemeMode(static_cast<int>(ThemeManager::Mode::Schedule)); });
|
||||
|
||||
QMenu *formatMenu = menuBar()->addMenu(tr("格式"));
|
||||
QMenu *headingMenu = formatMenu->addMenu(tr("标题"));
|
||||
m_languageMenu = m_viewMenu->addMenu(tr("语言"));
|
||||
QActionGroup *languageGroup = new QActionGroup(this);
|
||||
languageGroup->setExclusive(true);
|
||||
m_languageChineseAction =
|
||||
new QAction(LanguageManager::displayName(QStringLiteral("zh_CN")), this);
|
||||
m_languageEnglishAction =
|
||||
new QAction(LanguageManager::displayName(QStringLiteral("en")), this);
|
||||
for (QAction *action : {m_languageChineseAction, m_languageEnglishAction}) {
|
||||
action->setCheckable(true);
|
||||
languageGroup->addAction(action);
|
||||
m_languageMenu->addAction(action);
|
||||
}
|
||||
connect(m_languageChineseAction, &QAction::triggered, this,
|
||||
[this] { applyLanguage(QStringLiteral("zh_CN")); });
|
||||
connect(m_languageEnglishAction, &QAction::triggered, this,
|
||||
[this] { applyLanguage(QStringLiteral("en")); });
|
||||
|
||||
m_formatMenu = menuBar()->addMenu(tr("格式"));
|
||||
m_headingMenu = m_formatMenu->addMenu(tr("标题"));
|
||||
for (QAction *headingAction : m_headingActions) {
|
||||
if (headingAction)
|
||||
headingMenu->addAction(headingAction);
|
||||
m_headingMenu->addAction(headingAction);
|
||||
}
|
||||
formatMenu->addAction(m_codeBlockAction);
|
||||
m_formatMenu->addAction(m_codeBlockAction);
|
||||
|
||||
QMenu *helpMenu = menuBar()->addMenu(tr("帮助"));
|
||||
helpMenu->addAction(tr("关于 VoiletMark"), this, &MainWindow::showAbout);
|
||||
m_helpMenu = menuBar()->addMenu(tr("帮助"));
|
||||
m_aboutAction = m_helpMenu->addAction(tr("关于 VoiletMark"), this, &MainWindow::showAbout);
|
||||
}
|
||||
|
||||
void MainWindow::createStatusBar()
|
||||
@@ -446,9 +512,11 @@ QString MainWindow::startDirectory() const
|
||||
|
||||
void MainWindow::showWelcomeDocument()
|
||||
{
|
||||
QString text = QString::fromUtf8(kWelcomeText);
|
||||
const bool english = LanguageManager::instance()->language() == QLatin1String("en");
|
||||
QString text = QString::fromUtf8(english ? kWelcomeTextEn : kWelcomeText);
|
||||
if (text.startsWith(QLatin1Char('\n')))
|
||||
text.remove(0, 1);
|
||||
m_welcomeText = text;
|
||||
m_editor->setPlainText(text);
|
||||
m_editor->applyBlockRhythm();
|
||||
m_editor->document()->setModified(false);
|
||||
@@ -544,8 +612,37 @@ bool MainWindow::saveFileAs()
|
||||
|
||||
void MainWindow::exportPdf()
|
||||
{
|
||||
ExportDialog dialog(m_editor->toPlainText(), displayName(), startDirectory(), this);
|
||||
dialog.exec();
|
||||
QString suggested = m_currentPath.isEmpty() ? tr("未命名")
|
||||
: QFileInfo(m_currentPath).completeBaseName();
|
||||
suggested += QStringLiteral(".pdf");
|
||||
|
||||
QString target = QFileDialog::getSaveFileName(
|
||||
this, tr("导出 PDF"), QDir(startDirectory()).filePath(suggested),
|
||||
tr("PDF 文件 (*.pdf)"));
|
||||
if (target.isEmpty())
|
||||
return;
|
||||
if (!target.endsWith(QStringLiteral(".pdf"), Qt::CaseInsensitive))
|
||||
target += QStringLiteral(".pdf");
|
||||
|
||||
QTextDocument document;
|
||||
MarkdownRenderer::render(m_editor->toPlainText(), &document);
|
||||
document.setPageSize(QSizeF(672.76, 1001.57));
|
||||
|
||||
QPrinter printer(QPrinter::HighResolution);
|
||||
printer.setOutputFormat(QPrinter::PdfFormat);
|
||||
printer.setOutputFileName(target);
|
||||
printer.setPageSize(QPageSize(QPageSize::A4));
|
||||
printer.setPageMargins(QMarginsF(16, 16, 16, 16), QPageLayout::Millimeter);
|
||||
printer.setDocName(QFileInfo(target).completeBaseName());
|
||||
document.print(&printer);
|
||||
|
||||
if (!QFileInfo::exists(target) || QFileInfo(target).size() <= 0) {
|
||||
QMessageBox::warning(this, tr("导出失败"),
|
||||
tr("没能写出「%1」,换个位置再试一次。")
|
||||
.arg(QDir::toNativeSeparators(target)));
|
||||
return;
|
||||
}
|
||||
statusBar()->showMessage(tr("已导出 %1").arg(QDir::toNativeSeparators(target)), 4000);
|
||||
}
|
||||
|
||||
bool MainWindow::writeToFile(const QString &path)
|
||||
@@ -667,6 +764,83 @@ void MainWindow::applyThemeMode(int mode)
|
||||
ThemeManager::instance()->setMode(static_cast<ThemeManager::Mode>(mode), true);
|
||||
}
|
||||
|
||||
void MainWindow::applyLanguage(const QString &code)
|
||||
{
|
||||
LanguageManager::instance()->setLanguage(code);
|
||||
}
|
||||
|
||||
void MainWindow::retranslateUi()
|
||||
{
|
||||
m_fileMenu->setTitle(tr("文件"));
|
||||
m_editMenu->setTitle(tr("编辑"));
|
||||
m_viewMenu->setTitle(tr("视图"));
|
||||
m_formatMenu->setTitle(tr("格式"));
|
||||
m_helpMenu->setTitle(tr("帮助"));
|
||||
m_recentMenu->setTitle(tr("最近打开"));
|
||||
m_themeMenu->setTitle(tr("主题"));
|
||||
m_headingMenu->setTitle(tr("标题"));
|
||||
m_languageMenu->setTitle(tr("语言"));
|
||||
|
||||
m_newAction->setText(tr("新建"));
|
||||
m_openAction->setText(tr("打开…"));
|
||||
m_openFolderAction->setText(tr("打开文件夹…"));
|
||||
m_saveAction->setText(tr("保存"));
|
||||
m_saveAsAction->setText(tr("另存为…"));
|
||||
m_exportPdfAction->setText(tr("导出 PDF…"));
|
||||
m_quitAction->setText(tr("退出"));
|
||||
|
||||
m_undoAction->setText(tr("撤销"));
|
||||
m_redoAction->setText(tr("重做"));
|
||||
m_cutAction->setText(tr("剪切"));
|
||||
m_copyAction->setText(tr("复制"));
|
||||
m_pasteAction->setText(tr("粘贴"));
|
||||
m_selectAllAction->setText(tr("全选"));
|
||||
|
||||
m_sidebarAction->setText(tr("侧栏"));
|
||||
m_sourceModeAction->setText(tr("源代码模式"));
|
||||
m_wrapAction->setText(tr("自动换行"));
|
||||
m_zoomInAction->setText(tr("放大"));
|
||||
m_zoomOutAction->setText(tr("缩小"));
|
||||
m_zoomResetAction->setText(tr("实际大小"));
|
||||
|
||||
m_themeSystemAction->setText(ThemeManager::modeLabel(ThemeManager::Mode::System));
|
||||
m_themeLightAction->setText(ThemeManager::modeLabel(ThemeManager::Mode::Light));
|
||||
m_themeDarkAction->setText(ThemeManager::modeLabel(ThemeManager::Mode::Dark));
|
||||
m_themeScheduleAction->setText(ThemeManager::modeLabel(ThemeManager::Mode::Schedule));
|
||||
m_themeScheduleAction->setToolTip(tr("6:00–18:00 使用浅色,其余时间使用深色"));
|
||||
|
||||
for (int level = 1; level <= 6; ++level) {
|
||||
if (m_headingActions[level - 1])
|
||||
m_headingActions[level - 1]->setText(tr("标题 %1").arg(level));
|
||||
}
|
||||
m_codeBlockAction->setText(tr("代码块"));
|
||||
m_aboutAction->setText(tr("关于 VoiletMark"));
|
||||
|
||||
if (m_sidebarButton) {
|
||||
m_sidebarButton->setText(tr("侧栏"));
|
||||
m_sidebarButton->setToolTip(tr("显示 / 隐藏文件夹侧栏(Ctrl+B)"));
|
||||
}
|
||||
if (m_sourceButton)
|
||||
m_sourceButton->setToolTip(tr("源代码模式:关闭语法高亮与行号(Ctrl+Shift+M)"));
|
||||
|
||||
const QString language = LanguageManager::instance()->language();
|
||||
m_languageChineseAction->setChecked(language == QLatin1String("zh_CN"));
|
||||
m_languageEnglishAction->setChecked(language == QLatin1String("en"));
|
||||
|
||||
// 侧栏、最近打开、欢迎文档都跟着换
|
||||
m_displayedFolder.clear();
|
||||
refreshRecentMenu();
|
||||
refreshFolder();
|
||||
|
||||
if (m_currentPath.isEmpty() && !m_editor->document()->isModified()
|
||||
&& m_editor->toPlainText() == m_welcomeText) {
|
||||
showWelcomeDocument();
|
||||
}
|
||||
|
||||
updateWindowTitle();
|
||||
updateStatusBar();
|
||||
}
|
||||
|
||||
void MainWindow::showAbout()
|
||||
{
|
||||
QMessageBox box(this);
|
||||
|
||||
@@ -62,6 +62,8 @@ private:
|
||||
void resetZoom();
|
||||
void setWordWrapEnabled(bool enabled);
|
||||
void applyThemeMode(int mode);
|
||||
void applyLanguage(const QString &code);
|
||||
void retranslateUi();
|
||||
void showAbout();
|
||||
|
||||
void updateStatusBar();
|
||||
@@ -120,4 +122,18 @@ private:
|
||||
QAction *m_headingActions[6] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
|
||||
|
||||
QMenu *m_recentMenu = nullptr;
|
||||
QMenu *m_fileMenu = nullptr;
|
||||
QMenu *m_editMenu = nullptr;
|
||||
QMenu *m_viewMenu = nullptr;
|
||||
QMenu *m_formatMenu = nullptr;
|
||||
QMenu *m_helpMenu = nullptr;
|
||||
QMenu *m_themeMenu = nullptr;
|
||||
QMenu *m_headingMenu = nullptr;
|
||||
QMenu *m_languageMenu = nullptr;
|
||||
|
||||
QAction *m_aboutAction = nullptr;
|
||||
QAction *m_languageChineseAction = nullptr;
|
||||
QAction *m_languageEnglishAction = nullptr;
|
||||
|
||||
QString m_welcomeText;
|
||||
};
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "LanguageManager.h"
|
||||
#include "MainWindow.h"
|
||||
#include "ThemeManager.h"
|
||||
|
||||
@@ -51,6 +52,7 @@ int main(int argc, char *argv[])
|
||||
mode = ThemeManager::Mode::System;
|
||||
}
|
||||
ThemeManager::instance()->initialize(mode, false);
|
||||
LanguageManager::instance()->initialize();
|
||||
|
||||
MainWindow window;
|
||||
window.show();
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,395 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<TS version="2.1" language="en_US">
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="167" />
|
||||
<location filename="../src/MainWindow.cpp" line="781" />
|
||||
<source>新建</source>
|
||||
<translation>New</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="171" />
|
||||
<location filename="../src/MainWindow.cpp" line="782" />
|
||||
<source>打开…</source>
|
||||
<translation>Open…</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="175" />
|
||||
<location filename="../src/MainWindow.cpp" line="784" />
|
||||
<source>保存</source>
|
||||
<translation>Save</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="179" />
|
||||
<location filename="../src/MainWindow.cpp" line="785" />
|
||||
<source>另存为…</source>
|
||||
<translation>Save As…</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="183" />
|
||||
<location filename="../src/MainWindow.cpp" line="786" />
|
||||
<source>导出 PDF…</source>
|
||||
<translation>Export PDF…</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="187" />
|
||||
<location filename="../src/MainWindow.cpp" line="787" />
|
||||
<source>退出</source>
|
||||
<translation>Quit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="191" />
|
||||
<location filename="../src/MainWindow.cpp" line="789" />
|
||||
<source>撤销</source>
|
||||
<translation>Undo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="195" />
|
||||
<location filename="../src/MainWindow.cpp" line="790" />
|
||||
<source>重做</source>
|
||||
<translation>Redo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="199" />
|
||||
<location filename="../src/MainWindow.cpp" line="791" />
|
||||
<source>剪切</source>
|
||||
<translation>Cut</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="203" />
|
||||
<location filename="../src/MainWindow.cpp" line="792" />
|
||||
<source>复制</source>
|
||||
<translation>Copy</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="207" />
|
||||
<location filename="../src/MainWindow.cpp" line="793" />
|
||||
<source>粘贴</source>
|
||||
<translation>Paste</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="211" />
|
||||
<location filename="../src/MainWindow.cpp" line="794" />
|
||||
<source>全选</source>
|
||||
<translation>Select All</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="215" />
|
||||
<location filename="../src/MainWindow.cpp" line="798" />
|
||||
<source>自动换行</source>
|
||||
<translation>Word Wrap</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="220" />
|
||||
<location filename="../src/MainWindow.cpp" line="799" />
|
||||
<source>放大</source>
|
||||
<translation>Zoom In</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="224" />
|
||||
<location filename="../src/MainWindow.cpp" line="800" />
|
||||
<source>缩小</source>
|
||||
<translation>Zoom Out</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="228" />
|
||||
<location filename="../src/MainWindow.cpp" line="801" />
|
||||
<source>实际大小</source>
|
||||
<translation>Actual Size</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="237" />
|
||||
<location filename="../src/MainWindow.cpp" line="783" />
|
||||
<source>打开文件夹…</source>
|
||||
<translation>Open Folder…</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="241" />
|
||||
<location filename="../src/MainWindow.cpp" line="407" />
|
||||
<location filename="../src/MainWindow.cpp" line="796" />
|
||||
<location filename="../src/MainWindow.cpp" line="817" />
|
||||
<source>侧栏</source>
|
||||
<translation>Sidebar</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="255" />
|
||||
<location filename="../src/MainWindow.cpp" line="797" />
|
||||
<source>源代码模式</source>
|
||||
<translation>Source Mode</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="260" />
|
||||
<location filename="../src/MainWindow.cpp" line="813" />
|
||||
<source>代码块</source>
|
||||
<translation>Code Block</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="267" />
|
||||
<location filename="../src/MainWindow.cpp" line="811" />
|
||||
<source>标题 %1</source>
|
||||
<translation>Heading %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="278" />
|
||||
<source>文件夹</source>
|
||||
<translation>Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="289" />
|
||||
<location filename="../src/MainWindow.cpp" line="961" />
|
||||
<source>未打开文件夹</source>
|
||||
<translation>No folder open</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="315" />
|
||||
<location filename="../src/MainWindow.cpp" line="771" />
|
||||
<source>文件</source>
|
||||
<translation>File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="319" />
|
||||
<location filename="../src/MainWindow.cpp" line="776" />
|
||||
<source>最近打开</source>
|
||||
<translation>Recent Files</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="327" />
|
||||
<location filename="../src/MainWindow.cpp" line="772" />
|
||||
<source>编辑</source>
|
||||
<translation>Edit</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="337" />
|
||||
<location filename="../src/MainWindow.cpp" line="773" />
|
||||
<source>视图</source>
|
||||
<translation>View</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="348" />
|
||||
<location filename="../src/MainWindow.cpp" line="777" />
|
||||
<source>主题</source>
|
||||
<translation>Theme</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="356" />
|
||||
<location filename="../src/MainWindow.cpp" line="807" />
|
||||
<source>6:00–18:00 使用浅色,其余时间使用深色</source>
|
||||
<translation>Light from 6:00 to 18:00, dark the rest of the day</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="374" />
|
||||
<location filename="../src/MainWindow.cpp" line="779" />
|
||||
<source>语言</source>
|
||||
<translation>Language</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="391" />
|
||||
<location filename="../src/MainWindow.cpp" line="774" />
|
||||
<source>格式</source>
|
||||
<translation>Format</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="392" />
|
||||
<location filename="../src/MainWindow.cpp" line="778" />
|
||||
<source>标题</source>
|
||||
<translation>Heading</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="399" />
|
||||
<location filename="../src/MainWindow.cpp" line="775" />
|
||||
<source>帮助</source>
|
||||
<translation>Help</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="400" />
|
||||
<location filename="../src/MainWindow.cpp" line="814" />
|
||||
<location filename="../src/MainWindow.cpp" line="844" />
|
||||
<source>关于 VoiletMark</source>
|
||||
<translation>About VoiletMark</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="411" />
|
||||
<location filename="../src/MainWindow.cpp" line="818" />
|
||||
<source>显示 / 隐藏文件夹侧栏(Ctrl+B)</source>
|
||||
<translation>Show / hide the folder sidebar (Ctrl+B)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="419" />
|
||||
<location filename="../src/MainWindow.cpp" line="821" />
|
||||
<source>源代码模式:关闭语法高亮与行号(Ctrl+Shift+M)</source>
|
||||
<translation>Source mode: turn off highlighting and line numbers (Ctrl+Shift+M)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="497" />
|
||||
<location filename="../src/MainWindow.cpp" line="612" />
|
||||
<source>未命名</source>
|
||||
<translation>Untitled</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="546" />
|
||||
<source>打开 Markdown 文件</source>
|
||||
<translation>Open Markdown File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="547" />
|
||||
<source>Markdown 文件 (*.md *.markdown *.mdown *.mkd);;文本文件 (*.txt);;所有文件 (*)</source>
|
||||
<translation>Markdown files (*.md *.markdown *.mdown *.mkd);;Text files (*.txt);;All files (*)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="564" />
|
||||
<source>无法打开文件</source>
|
||||
<translation>Cannot Open File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="565" />
|
||||
<source>读取「%1」失败:%2</source>
|
||||
<translation>Could not read "%1": %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="599" />
|
||||
<source>另存为</source>
|
||||
<translation>Save As</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="600" />
|
||||
<source>Markdown 文件 (*.md);;文本文件 (*.txt);;所有文件 (*)</source>
|
||||
<translation>Markdown files (*.md);;Text files (*.txt);;All files (*)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="617" />
|
||||
<source>导出 PDF</source>
|
||||
<translation>Export PDF</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="618" />
|
||||
<source>PDF 文件 (*.pdf)</source>
|
||||
<translation>PDF files (*.pdf)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="637" />
|
||||
<source>导出失败</source>
|
||||
<translation>Export Failed</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="638" />
|
||||
<source>没能写出「%1」,换个位置再试一次。</source>
|
||||
<translation>Could not write "%1". Try another location.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="642" />
|
||||
<source>已导出 %1</source>
|
||||
<translation>Exported to %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="657" />
|
||||
<location filename="../src/MainWindow.cpp" line="664" />
|
||||
<location filename="../src/MainWindow.cpp" line="669" />
|
||||
<source>无法保存文件</source>
|
||||
<translation>Cannot Save File</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="658" />
|
||||
<source>写入「%1」失败:%2</source>
|
||||
<translation>Could not write "%1": %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="665" />
|
||||
<source>写入「%1」时发生错误。</source>
|
||||
<translation>An error occurred while writing "%1".</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="670" />
|
||||
<source>提交「%1」失败:%2</source>
|
||||
<translation>Could not commit "%1": %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="678" />
|
||||
<source>已保存 %1</source>
|
||||
<translation>Saved to %1</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="688" />
|
||||
<source>VoiletMark</source>
|
||||
<translation>VoiletMark</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="689" />
|
||||
<source>「%1」有未保存的修改,是否保存?</source>
|
||||
<translation>"%1" has unsaved changes. Save them?</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="713" />
|
||||
<source>%1[*] — VoiletMark</source>
|
||||
<translation>%1[*] — VoiletMark</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="732" />
|
||||
<source>行 %1,列 %2</source>
|
||||
<translation>Line %1, Col %2</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="734" />
|
||||
<source> 已选 %1 字</source>
|
||||
<translation> %1 selected</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="735" />
|
||||
<source> %1 字</source>
|
||||
<translation> %1 chars</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="848" />
|
||||
<source><h3>VoiletMark %1</h3><p>一个轻量的跨平台 Markdown 编辑器。</p><p>基于 Qt %2 与 C++17 构建。</p></source>
|
||||
<translation><h3>VoiletMark %1</h3><p>A lightweight cross-platform Markdown editor.</p><p>Built with Qt %2 and C++17.</p></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="883" />
|
||||
<source>(暂无记录)</source>
|
||||
<translation>(none)</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="896" />
|
||||
<source>清空列表</source>
|
||||
<translation>Clear List</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="906" />
|
||||
<source>打开文件夹</source>
|
||||
<translation>Open Folder</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="962" />
|
||||
<source>文件 → 打开文件夹…</source>
|
||||
<translation>File → Open Folder…</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/MainWindow.cpp" line="998" />
|
||||
<source>(没有 Markdown 文件)</source>
|
||||
<translation>(no Markdown files)</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>QObject</name>
|
||||
<message>
|
||||
<location filename="../src/ThemeManager.cpp" line="354" />
|
||||
<source>浅色</source>
|
||||
<translation>Light</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/ThemeManager.cpp" line="355" />
|
||||
<source>深色</source>
|
||||
<translation>Dark</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/ThemeManager.cpp" line="356" />
|
||||
<source>按时段自动</source>
|
||||
<translation>Scheduled</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/ThemeManager.cpp" line="359" />
|
||||
<source>跟随系统</source>
|
||||
<translation>Follow System</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
Reference in New Issue
Block a user