feat: v0.10.0 —— 表格可编辑控件,单行代码块的语言按钮挪位

代码块
- 只有一行代码时,框太矮,语言下拉自动挪到复制按钮左边同一行

表格
- 检测 Markdown 表格(表头 + |---| 分隔行 + 连续 | 行),在编辑模式下用
  QTableWidget 覆盖渲染:圆角边框、网格线、表头加粗、按 :---: 保留对齐
- 双击单元格直接编辑,改完立刻回写成 Markdown 表格
- 右键菜单:插入行 / 删除行 / 插入列 / 删除列,改完同步回文本
- 新增行/列会沿用原有对齐;表格增删行后自动修正后面表格的行号偏移
- 源代码模式下表格退回原始 Markdown 文本(控件隐藏)
- 主题切换时重建控件以套用新配色

其它
- 欢迎文档与演示文档各加一张示例表格
- 新增 4 条中英文翻译(插入行/删除行/插入列/删除列)
- 版本 0.10.0
This commit is contained in:
2026-10-22 18:32:56 +08:00
parent e24474abd1
commit 0a6a3f8775
10 changed files with 581 additions and 164 deletions
+6 -3
View File
@@ -2,7 +2,7 @@
一个轻量的跨平台 Markdown 编辑器,基于 **Qt 5 / C++17** 构建。 一个轻量的跨平台 Markdown 编辑器,基于 **Qt 5 / C++17** 构建。
当前版本 **0.9.1**。 当前版本 **0.10.0**。
## 界面 ## 界面
@@ -29,8 +29,11 @@
- 代码块按语言做语法高亮:C / C++ / Python / JavaScript / TypeScript / - 代码块按语言做语法高亮:C / C++ / Python / JavaScript / TypeScript /
Java / Rust / Go / JSON / Bash / SQL / YAML,关键字、字符串、数字、 Java / Rust / Go / JSON / Bash / SQL / YAML,关键字、字符串、数字、
注释、预处理指令分色;不认识的标记语言就按等宽纯文本显示 注释、预处理指令分色;不认识的标记语言就按等宽纯文本显示
- 代码框**左上角**是语言下拉菜单,选一下就会改写围栏上的语言标记, - 代码框**右下角**是语言下拉菜单,选一下就会改写围栏上的语言标记,
高亮立刻跟着变(选「纯文本」则去掉语言) 高亮立刻跟着变(选「纯文本」则去掉语言);只有一行代码时它挪到复制按钮左边
- 表格渲染成带网格的表格控件:双击单元格直接编辑,右键可**插入 / 删除行、插入 / 删除列**,
改完立刻回写成 Markdown 表格,对齐方式(`:---:`)也会保留
- 源代码模式下表格退回原始 Markdown 文本
- `Tab` / `Shift+Tab` 整行缩进,选中多行时批量缩进 - `Tab` / `Shift+Tab` 整行缩进,选中多行时批量缩进
- 自动换行(`Alt+Z`)、`Ctrl+滚轮` 或 `Ctrl++` / `Ctrl+-` 缩放字号 - 自动换行(`Alt+Z`)、`Ctrl+滚轮` 或 `Ctrl++` / `Ctrl+-` 缩放字号
- 撤销 / 重做、剪切 / 复制 / 粘贴,菜单项会跟随可用状态自动灰显 - 撤销 / 重做、剪切 / 复制 / 粘贴,菜单项会跟随可用状态自动灰显
+1 -1
View File
@@ -1,6 +1,6 @@
TEMPLATE = app TEMPLATE = app
TARGET = VoiletMark TARGET = VoiletMark
VERSION = 0.9.1 VERSION = 0.10.0
QT += core gui widgets printsupport QT += core gui widgets printsupport
Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 126 KiB

+12
View File
@@ -76,6 +76,12 @@ const char kWelcomeText[] = R"VOILETMARK(
1. 有序列表项 1. 有序列表项
2. 另一个有序列表项 2. 另一个有序列表项
| 功能 | 状态 |
| --- | :---: |
| 语法高亮 | 完成 |
| 导出 PDF | 完成 |
| Git 同步 | 完成 |
- [x] 自动深浅色主题 - [x] 自动深浅色主题
- [x] Markdown 语法高亮 - [x] Markdown 语法高亮
- [x] 导出 PDF - [x] 导出 PDF
@@ -119,6 +125,12 @@ switch it under **View → Theme**.
> Quotes, lists, `inline code`, **bold**, *italic*, ~~strikethrough~~ > Quotes, lists, `inline code`, **bold**, *italic*, ~~strikethrough~~
> and [links](https://example.com) all render in place. > and [links](https://example.com) all render in place.
| Feature | Status |
| --- | :---: |
| Syntax highlighting | Done |
| PDF export | Done |
| Git sync | Done |
- [x] Syntax highlighting - [x] Syntax highlighting
- [x] Folder sidebar - [x] Folder sidebar
- [x] PDF export - [x] PDF export
+361 -1
View File
@@ -11,6 +11,7 @@
#include <QFontDatabase> #include <QFontDatabase>
#include <QFontMetricsF> #include <QFontMetricsF>
#include <QGuiApplication> #include <QGuiApplication>
#include <QHeaderView>
#include <QKeyEvent> #include <QKeyEvent>
#include <QMenu> #include <QMenu>
#include <QMouseEvent> #include <QMouseEvent>
@@ -20,6 +21,7 @@
#include <QRegularExpression> #include <QRegularExpression>
#include <QTextBlock> #include <QTextBlock>
#include <QTextCursor> #include <QTextCursor>
#include <QTableWidget>
#include <QTextOption> #include <QTextOption>
#include <QTimer> #include <QTimer>
#include <QUrl> #include <QUrl>
@@ -123,8 +125,20 @@ MarkdownEditor::MarkdownEditor(QWidget *parent)
m_fenceTimer = new QTimer(this); m_fenceTimer = new QTimer(this);
m_fenceTimer->setSingleShot(true); m_fenceTimer->setSingleShot(true);
m_fenceTimer->setInterval(120); m_fenceTimer->setInterval(120);
connect(m_fenceTimer, &QTimer::timeout, this, &MarkdownEditor::rebuildCodeFences); connect(m_fenceTimer, &QTimer::timeout, this, [this] {
rebuildCodeFences();
if (m_updatingTable)
return;
if (m_skipTableRebuild) {
m_skipTableRebuild = false;
positionTableWidgets();
return;
}
rebuildTables();
});
connect(this, &QPlainTextEdit::textChanged, this, [this] { m_fenceTimer->start(); }); connect(this, &QPlainTextEdit::textChanged, this, [this] { m_fenceTimer->start(); });
connect(this, &QPlainTextEdit::updateRequest, this,
[this](const QRect &, int) { positionTableWidgets(); });
m_lineNumberArea->setVisible(m_sourceMode); m_lineNumberArea->setVisible(m_sourceMode);
applyEditorFont(); applyEditorFont();
@@ -252,6 +266,7 @@ void MarkdownEditor::applyTheme()
{ {
updateCurrentLineHighlight(); updateCurrentLineHighlight();
m_lineNumberArea->update(); m_lineNumberArea->update();
rebuildTables();
viewport()->update(); viewport()->update();
} }
@@ -293,6 +308,7 @@ void MarkdownEditor::setSourceMode(bool enabled)
applyEditorFont(); applyEditorFont();
updateViewportMargins(); updateViewportMargins();
updateCurrentLineHighlight(); updateCurrentLineHighlight();
rebuildTables();
viewport()->update(); viewport()->update();
emit sourceModeChanged(enabled); emit sourceModeChanged(enabled);
} }
@@ -594,6 +610,16 @@ QRectF MarkdownEditor::languageRect(int index) const
const QString label = languageLabel(index) + QStringLiteral(" \u25be"); const QString label = languageLabel(index) + QStringLiteral(" \u25be");
const qreal width = metrics.horizontalAdvance(label) + 16; const qreal width = metrics.horizontalAdvance(label) + 16;
const qreal height = metrics.height() + 6; const qreal height = metrics.height() + 6;
// 只有一行代码时,框太矮,把语言徽标挪到复制按钮左边同一行。
const CodeFence &fence = m_codeFences.at(index);
const int lastLine = fence.close >= 0 ? fence.close : document()->blockCount() - 1;
const int contentLines = lastLine - fence.open - 1;
if (contentLines <= 1) {
const QRectF copy = copyButtonRect(index);
return QRectF(copy.left() - width - 6, copy.top(), width, height);
}
return QRectF(rect.right() - width - 8, rect.bottom() - height - 6, width, height); return QRectF(rect.right() - width - 8, rect.bottom() - height - 6, width, height);
} }
@@ -909,3 +935,337 @@ void MarkdownEditor::dropEvent(QDropEvent *event)
} }
QPlainTextEdit::dropEvent(event); QPlainTextEdit::dropEvent(event);
} }
// ---------------------------------------------------------------- 表格
namespace {
bool isTableSeparatorLine(const QString &text)
{
static const QRegularExpression pattern(
QStringLiteral(R"(^\s*\|?\s*:?-{2,}:?\s*(?:\|\s*:?-{2,}:?\s*)+\|?\s*$)"));
return pattern.match(text).hasMatch();
}
QStringList splitTableRow(const QString &line)
{
QString text = line.trimmed();
if (text.startsWith(QLatin1Char('|')))
text.remove(0, 1);
if (text.endsWith(QLatin1Char('|')))
text.chop(1);
QStringList cells = text.split(QLatin1Char('|'));
for (QString &cell : cells)
cell = cell.trimmed();
return cells;
}
} // namespace
void MarkdownEditor::rebuildTables()
{
for (TableInfo &table : m_tables) {
if (table.widget) {
table.widget->deleteLater();
table.widget = nullptr;
}
}
m_tables.clear();
if (m_sourceMode || !document())
return;
QTextBlock block = document()->firstBlock();
while (block.isValid()) {
if (!block.text().contains(QLatin1Char('|'))) {
block = block.next();
continue;
}
const QTextBlock separator = block.next();
if (!separator.isValid() || !isTableSeparatorLine(separator.text())) {
block = block.next();
continue;
}
TableInfo table;
table.firstBlock = block.blockNumber();
int last = separator.blockNumber();
QTextBlock cursor = separator.next();
while (cursor.isValid() && !cursor.text().trimmed().isEmpty()
&& cursor.text().contains(QLatin1Char('|'))) {
last = cursor.blockNumber();
cursor = cursor.next();
}
table.lastBlock = last;
for (const QString &cell : splitTableRow(separator.text())) {
const bool left = cell.startsWith(QLatin1Char(':'));
const bool right = cell.endsWith(QLatin1Char(':'));
if (left && right)
table.alignments.append(Qt::AlignHCenter);
else if (right)
table.alignments.append(Qt::AlignRight);
else
table.alignments.append(Qt::AlignLeft);
}
m_tables.append(table);
block = document()->findBlockByNumber(last).next();
}
for (int index = 0; index < m_tables.size(); ++index)
createTableWidget(index);
positionTableWidgets();
}
void MarkdownEditor::createTableWidget(int index)
{
TableInfo &table = m_tables[index];
const QTextBlock first = document()->findBlockByNumber(table.firstBlock);
if (!first.isValid())
return;
auto *widget = new QTableWidget(viewport());
widget->setObjectName(QStringLiteral("markdownTable"));
widget->setFrameShape(QFrame::NoFrame);
widget->setShowGrid(true);
widget->setWordWrap(true);
widget->horizontalHeader()->hide();
widget->verticalHeader()->hide();
widget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
widget->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
widget->setSelectionMode(QAbstractItemView::SingleSelection);
widget->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked
| QAbstractItemView::EditKeyPressed);
widget->setContextMenuPolicy(Qt::CustomContextMenu);
widget->setFont(font());
const ThemeColors &colors = ThemeManager::instance()->colors();
widget->setStyleSheet(
QStringLiteral("QTableWidget { background: %1; color: %2; border: 1px solid %3;"
" border-radius: 6px; gridline-color: %3; }"
"QTableWidget::item { padding: 2px 6px; }"
"QTableWidget::item:selected { background: %4; color: %5; }")
.arg(colors.editorBase.name(), colors.editorText.name(), colors.border.name(),
colors.highlight.name(), colors.highlightedText.name()));
{
const QSignalBlocker blocker(widget);
const QStringList header = splitTableRow(first.text());
widget->setColumnCount(qMax(1, header.size()));
widget->setRowCount(1);
for (int column = 0; column < header.size(); ++column) {
auto *item = new QTableWidgetItem(header.at(column));
QFont itemFont = item->font();
itemFont.setBold(true);
item->setFont(itemFont);
item->setTextAlignment(table.alignments.value(column, Qt::AlignLeft) | Qt::AlignVCenter);
widget->setItem(0, column, item);
}
int row = 1;
for (int number = table.firstBlock + 2; number <= table.lastBlock; ++number, ++row) {
const QStringList cells = splitTableRow(document()->findBlockByNumber(number).text());
widget->insertRow(row);
for (int column = 0; column < widget->columnCount(); ++column) {
auto *item = new QTableWidgetItem(cells.value(column));
item->setTextAlignment(table.alignments.value(column, Qt::AlignLeft)
| Qt::AlignVCenter);
widget->setItem(row, column, item);
}
}
}
connect(widget, &QTableWidget::itemChanged, this, [this, widget](QTableWidgetItem *) {
if (m_updatingTable)
return;
const int current = tableIndexFor(widget);
if (current >= 0)
applyTableEdit(current);
});
connect(widget, &QWidget::customContextMenuRequested, this, [this, widget](const QPoint &pos) {
const int current = tableIndexFor(widget);
if (current < 0)
return;
QMenu menu(this);
menu.addAction(tr("插入行"), this, [this, widget, current] {
const int row = qBound(1, widget->currentRow() + 1, widget->rowCount());
{
const QSignalBlocker blocker(widget);
widget->insertRow(row);
for (int column = 0; column < widget->columnCount(); ++column) {
auto *item = new QTableWidgetItem;
item->setTextAlignment(m_tables.at(current).alignments.value(column,
Qt::AlignLeft)
| Qt::AlignVCenter);
widget->setItem(row, column, item);
}
}
applyTableEdit(current);
});
menu.addAction(tr("删除行"), this, [this, widget, current] {
if (widget->rowCount() <= 2)
return;
{
const QSignalBlocker blocker(widget);
widget->removeRow(qMax(1, widget->currentRow()));
}
applyTableEdit(current);
});
menu.addSeparator();
menu.addAction(tr("插入列"), this, [this, widget, current] {
const int column = qBound(0, widget->currentColumn() + 1, widget->columnCount());
{
const QSignalBlocker blocker(widget);
widget->insertColumn(column);
for (int row = 0; row < widget->rowCount(); ++row) {
auto *item = new QTableWidgetItem;
item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
widget->setItem(row, column, item);
}
if (column <= m_tables.at(current).alignments.size())
m_tables[current].alignments.insert(column, Qt::AlignLeft);
}
applyTableEdit(current);
});
menu.addAction(tr("删除列"), this, [this, widget, current] {
if (widget->columnCount() <= 1)
return;
const int column = qMax(0, widget->currentColumn());
{
const QSignalBlocker blocker(widget);
widget->removeColumn(column);
if (column < m_tables.at(current).alignments.size())
m_tables[current].alignments.remove(column);
}
applyTableEdit(current);
});
menu.exec(widget->viewport()->mapToGlobal(pos));
});
table.widget = widget;
}
int MarkdownEditor::tableIndexFor(const QTableWidget *widget) const
{
for (int index = 0; index < m_tables.size(); ++index) {
if (m_tables.at(index).widget == widget)
return index;
}
return -1;
}
void MarkdownEditor::applyTableEdit(int index)
{
if (index < 0 || index >= m_tables.size())
return;
TableInfo &table = m_tables[index];
QTableWidget *widget = table.widget;
if (!widget)
return;
const int columns = widget->columnCount();
QStringList headerCells;
for (int column = 0; column < columns; ++column) {
const QTableWidgetItem *item = widget->item(0, column);
headerCells << (item ? item->text().trimmed() : QString());
}
QStringList separatorCells;
for (int column = 0; column < columns; ++column) {
switch (table.alignments.value(column, Qt::AlignLeft)) {
case Qt::AlignHCenter:
separatorCells << QStringLiteral(":---:");
break;
case Qt::AlignRight:
separatorCells << QStringLiteral("---:");
break;
default:
separatorCells << QStringLiteral("---");
break;
}
}
QStringList lines;
lines << (QStringLiteral("| ") + headerCells.join(QStringLiteral(" | ")) + QStringLiteral(" |"));
lines << (QStringLiteral("| ") + separatorCells.join(QStringLiteral(" | "))
+ QStringLiteral(" |"));
for (int row = 1; row < widget->rowCount(); ++row) {
QStringList cells;
for (int column = 0; column < columns; ++column) {
const QTableWidgetItem *item = widget->item(row, column);
cells << (item ? item->text().trimmed() : QString());
}
lines << (QStringLiteral("| ") + cells.join(QStringLiteral(" | ")) + QStringLiteral(" |"));
}
replaceTableText(index, lines);
}
void MarkdownEditor::replaceTableText(int index, const QStringList &lines)
{
if (index < 0 || index >= m_tables.size() || lines.isEmpty())
return;
TableInfo &table = m_tables[index];
const QTextBlock first = document()->findBlockByNumber(table.firstBlock);
const QTextBlock last = document()->findBlockByNumber(table.lastBlock);
if (!first.isValid() || !last.isValid())
return;
const int oldCount = table.lastBlock - table.firstBlock + 1;
const int delta = lines.size() - oldCount;
m_updatingTable = true;
QTextCursor cursor(first);
cursor.beginEditBlock();
cursor.setPosition(first.position());
cursor.setPosition(last.position() + last.text().length(), QTextCursor::KeepAnchor);
cursor.insertText(lines.join(QLatin1Char('\n')));
cursor.endEditBlock();
m_updatingTable = false;
m_skipTableRebuild = true;
table.lastBlock = table.firstBlock + lines.size() - 1;
for (int other = index + 1; other < m_tables.size(); ++other) {
m_tables[other].firstBlock += delta;
m_tables[other].lastBlock += delta;
}
positionTableWidgets();
}
QRectF MarkdownEditor::tableRect(const TableInfo &table) const
{
const QTextBlock first = document()->findBlockByNumber(table.firstBlock);
const QTextBlock last = document()->findBlockByNumber(table.lastBlock);
if (!first.isValid() || !last.isValid())
return QRectF();
const QRectF top = blockBoundingGeometry(first).translated(contentOffset());
const QRectF bottom = blockBoundingGeometry(last).translated(contentOffset());
return QRectF(3, top.top() - 2, viewport()->width() - 6, bottom.bottom() - top.top() + 4);
}
void MarkdownEditor::positionTableWidgets()
{
const QRectF visible(viewport()->rect());
for (TableInfo &table : m_tables) {
if (!table.widget)
continue;
const QRectF rect = tableRect(table);
if (!rect.isValid() || m_sourceMode) {
table.widget->hide();
continue;
}
table.widget->setGeometry(rect.toRect());
table.widget->setVisible(rect.intersects(visible));
}
}
+22
View File
@@ -8,6 +8,7 @@
class MarkdownHighlighter; class MarkdownHighlighter;
class QTextBlock; class QTextBlock;
class QTimer; class QTimer;
class QTableWidget;
/// 编辑器本体:等宽字体、行号栏、当前行高亮、Tab 缩进、 /// 编辑器本体:等宽字体、行号栏、当前行高亮、Tab 缩进、
/// Ctrl+滚轮缩放,以及把拖入的文件转交给主窗口打开。 /// Ctrl+滚轮缩放,以及把拖入的文件转交给主窗口打开。
@@ -63,6 +64,8 @@ private slots:
void rebuildCodeFences(); void rebuildCodeFences();
private: private:
struct TableInfo;
void applyEditorFont(); void applyEditorFont();
void updateViewportMargins(); void updateViewportMargins();
void indentSelection(bool outdent); void indentSelection(bool outdent);
@@ -73,6 +76,15 @@ private:
QString languageLabel(int index) const; QString languageLabel(int index) const;
void showLanguageMenu(int index); void showLanguageMenu(int index);
void setCodeFenceLanguage(int index, const QString &info); void setCodeFenceLanguage(int index, const QString &info);
// ---- 表格 ----
void rebuildTables();
void positionTableWidgets();
QRectF tableRect(const TableInfo &table) const;
void createTableWidget(int index);
void applyTableEdit(int index);
void replaceTableText(int index, const QStringList &lines);
int tableIndexFor(const QTableWidget *widget) const;
bool acceptsLocalFiles(const QMimeData *mime) const; bool acceptsLocalFiles(const QMimeData *mime) const;
void selectedBlockRange(int *firstBlock, int *lastBlock) const; void selectedBlockRange(int *firstBlock, int *lastBlock) const;
void selectBlocks(int firstBlock, int lastBlock); void selectBlocks(int firstBlock, int lastBlock);
@@ -86,6 +98,13 @@ private:
CodeHighlight::Language language = CodeHighlight::Language::None; CodeHighlight::Language language = CodeHighlight::Language::None;
}; };
struct TableInfo {
int firstBlock = -1;
int lastBlock = -1;
QTableWidget *widget = nullptr;
QVector<Qt::Alignment> alignments;
};
QWidget *m_lineNumberArea = nullptr; QWidget *m_lineNumberArea = nullptr;
MarkdownHighlighter *m_highlighter = nullptr; MarkdownHighlighter *m_highlighter = nullptr;
int m_fontPointSize = 12; int m_fontPointSize = 12;
@@ -93,6 +112,9 @@ private:
int m_activeBlock = -1; int m_activeBlock = -1;
QVector<CodeFence> m_codeFences; QVector<CodeFence> m_codeFences;
QVector<TableInfo> m_tables;
bool m_updatingTable = false;
bool m_skipTableRebuild = false;
QTimer *m_fenceTimer = nullptr; QTimer *m_fenceTimer = nullptr;
int m_hoveredFence = -1; int m_hoveredFence = -1;
int m_hoveredLanguage = -1; int m_hoveredLanguage = -1;
Binary file not shown.
+179 -159
View File
@@ -13,448 +13,448 @@
<context> <context>
<name>MainWindow</name> <name>MainWindow</name>
<message> <message>
<location filename="../src/MainWindow.cpp" line="179" /> <location filename="../src/MainWindow.cpp" line="191" />
<location filename="../src/MainWindow.cpp" line="837" /> <location filename="../src/MainWindow.cpp" line="849" />
<source>新建</source> <source>新建</source>
<translation>New</translation> <translation>New</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="183" /> <location filename="../src/MainWindow.cpp" line="195" />
<location filename="../src/MainWindow.cpp" line="838" /> <location filename="../src/MainWindow.cpp" line="850" />
<source>打开…</source> <source>打开…</source>
<translation>Open…</translation> <translation>Open…</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="187" /> <location filename="../src/MainWindow.cpp" line="199" />
<location filename="../src/MainWindow.cpp" line="840" /> <location filename="../src/MainWindow.cpp" line="852" />
<source>保存</source> <source>保存</source>
<translation>Save</translation> <translation>Save</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="191" /> <location filename="../src/MainWindow.cpp" line="203" />
<location filename="../src/MainWindow.cpp" line="841" /> <location filename="../src/MainWindow.cpp" line="853" />
<source>另存为…</source> <source>另存为…</source>
<translation>Save As…</translation> <translation>Save As…</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="195" /> <location filename="../src/MainWindow.cpp" line="207" />
<location filename="../src/MainWindow.cpp" line="842" /> <location filename="../src/MainWindow.cpp" line="854" />
<source>导出 PDF…</source> <source>导出 PDF…</source>
<translation>Export PDF…</translation> <translation>Export PDF…</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="199" /> <location filename="../src/MainWindow.cpp" line="211" />
<location filename="../src/MainWindow.cpp" line="843" /> <location filename="../src/MainWindow.cpp" line="855" />
<source>退出</source> <source>退出</source>
<translation>Quit</translation> <translation>Quit</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="203" /> <location filename="../src/MainWindow.cpp" line="215" />
<location filename="../src/MainWindow.cpp" line="845" /> <location filename="../src/MainWindow.cpp" line="857" />
<source>撤销</source> <source>撤销</source>
<translation>Undo</translation> <translation>Undo</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="207" /> <location filename="../src/MainWindow.cpp" line="219" />
<location filename="../src/MainWindow.cpp" line="846" /> <location filename="../src/MainWindow.cpp" line="858" />
<source>重做</source> <source>重做</source>
<translation>Redo</translation> <translation>Redo</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="211" /> <location filename="../src/MainWindow.cpp" line="223" />
<location filename="../src/MainWindow.cpp" line="847" /> <location filename="../src/MainWindow.cpp" line="859" />
<source>剪切</source> <source>剪切</source>
<translation>Cut</translation> <translation>Cut</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="215" /> <location filename="../src/MainWindow.cpp" line="227" />
<location filename="../src/MainWindow.cpp" line="848" /> <location filename="../src/MainWindow.cpp" line="860" />
<source>复制</source> <source>复制</source>
<translation>Copy</translation> <translation>Copy</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="219" /> <location filename="../src/MainWindow.cpp" line="231" />
<location filename="../src/MainWindow.cpp" line="849" /> <location filename="../src/MainWindow.cpp" line="861" />
<source>粘贴</source> <source>粘贴</source>
<translation>Paste</translation> <translation>Paste</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="223" /> <location filename="../src/MainWindow.cpp" line="235" />
<location filename="../src/MainWindow.cpp" line="850" /> <location filename="../src/MainWindow.cpp" line="862" />
<source>全选</source> <source>全选</source>
<translation>Select All</translation> <translation>Select All</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="227" /> <location filename="../src/MainWindow.cpp" line="239" />
<location filename="../src/MainWindow.cpp" line="854" /> <location filename="../src/MainWindow.cpp" line="866" />
<source>自动换行</source> <source>自动换行</source>
<translation>Word Wrap</translation> <translation>Word Wrap</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="232" /> <location filename="../src/MainWindow.cpp" line="244" />
<location filename="../src/MainWindow.cpp" line="855" /> <location filename="../src/MainWindow.cpp" line="867" />
<source>放大</source> <source>放大</source>
<translation>Zoom In</translation> <translation>Zoom In</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="236" /> <location filename="../src/MainWindow.cpp" line="248" />
<location filename="../src/MainWindow.cpp" line="856" /> <location filename="../src/MainWindow.cpp" line="868" />
<source>缩小</source> <source>缩小</source>
<translation>Zoom Out</translation> <translation>Zoom Out</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="240" /> <location filename="../src/MainWindow.cpp" line="252" />
<location filename="../src/MainWindow.cpp" line="857" /> <location filename="../src/MainWindow.cpp" line="869" />
<source>实际大小</source> <source>实际大小</source>
<translation>Actual Size</translation> <translation>Actual Size</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="249" /> <location filename="../src/MainWindow.cpp" line="261" />
<location filename="../src/MainWindow.cpp" line="839" /> <location filename="../src/MainWindow.cpp" line="851" />
<source>打开文件夹…</source> <source>打开文件夹…</source>
<translation>Open Folder…</translation> <translation>Open Folder…</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="253" /> <location filename="../src/MainWindow.cpp" line="265" />
<location filename="../src/MainWindow.cpp" line="461" /> <location filename="../src/MainWindow.cpp" line="473" />
<location filename="../src/MainWindow.cpp" line="852" /> <location filename="../src/MainWindow.cpp" line="864" />
<location filename="../src/MainWindow.cpp" line="873" /> <location filename="../src/MainWindow.cpp" line="885" />
<source>侧栏</source> <source>侧栏</source>
<translation>Sidebar</translation> <translation>Sidebar</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="267" /> <location filename="../src/MainWindow.cpp" line="279" />
<location filename="../src/MainWindow.cpp" line="853" /> <location filename="../src/MainWindow.cpp" line="865" />
<source>源代码模式</source> <source>源代码模式</source>
<translation>Source Mode</translation> <translation>Source Mode</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="272" /> <location filename="../src/MainWindow.cpp" line="284" />
<location filename="../src/MainWindow.cpp" line="869" /> <location filename="../src/MainWindow.cpp" line="881" />
<source>代码块</source> <source>代码块</source>
<translation>Code Block</translation> <translation>Code Block</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="279" /> <location filename="../src/MainWindow.cpp" line="291" />
<location filename="../src/MainWindow.cpp" line="867" /> <location filename="../src/MainWindow.cpp" line="879" />
<source>标题 %1</source> <source>标题 %1</source>
<translation>Heading %1</translation> <translation>Heading %1</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="290" /> <location filename="../src/MainWindow.cpp" line="302" />
<source>文件夹</source> <source>文件夹</source>
<translation>Folder</translation> <translation>Folder</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="301" /> <location filename="../src/MainWindow.cpp" line="313" />
<location filename="../src/MainWindow.cpp" line="1018" /> <location filename="../src/MainWindow.cpp" line="1030" />
<source>未打开文件夹</source> <source>未打开文件夹</source>
<translation>No folder open</translation> <translation>No folder open</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="319" /> <location filename="../src/MainWindow.cpp" line="331" />
<location filename="../src/MainWindow.cpp" line="1151" /> <location filename="../src/MainWindow.cpp" line="1163" />
<source>Git 仓库</source> <source>Git 仓库</source>
<translation>Git repository</translation> <translation>Git repository</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="331" /> <location filename="../src/MainWindow.cpp" line="343" />
<location filename="../src/MainWindow.cpp" line="1216" /> <location filename="../src/MainWindow.cpp" line="1228" />
<source>拉取</source> <source>拉取</source>
<translation>Pull</translation> <translation>Pull</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="331" /> <location filename="../src/MainWindow.cpp" line="343" />
<source>git pull --ff-only</source> <source>git pull --ff-only</source>
<translation>git pull --ff-only</translation> <translation>git pull --ff-only</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="332" /> <location filename="../src/MainWindow.cpp" line="344" />
<location filename="../src/MainWindow.cpp" line="1224" /> <location filename="../src/MainWindow.cpp" line="1236" />
<source>获取</source> <source>获取</source>
<translation>Fetch</translation> <translation>Fetch</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="332" /> <location filename="../src/MainWindow.cpp" line="344" />
<source>git fetch --all --prune</source> <source>git fetch --all --prune</source>
<translation>git fetch --all --prune</translation> <translation>git fetch --all --prune</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="333" /> <location filename="../src/MainWindow.cpp" line="345" />
<location filename="../src/MainWindow.cpp" line="1231" /> <location filename="../src/MainWindow.cpp" line="1243" />
<location filename="../src/MainWindow.cpp" line="1339" /> <location filename="../src/MainWindow.cpp" line="1351" />
<source>推送</source> <source>推送</source>
<translation>Push</translation> <translation>Push</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="333" /> <location filename="../src/MainWindow.cpp" line="345" />
<source>git push</source> <source>git push</source>
<translation>git push</translation> <translation>git push</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="334" /> <location filename="../src/MainWindow.cpp" line="346" />
<location filename="../src/MainWindow.cpp" line="1238" /> <location filename="../src/MainWindow.cpp" line="1250" />
<source>暂存</source> <source>暂存</source>
<translation>Stage</translation> <translation>Stage</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="334" /> <location filename="../src/MainWindow.cpp" line="346" />
<source>git add -A</source> <source>git add -A</source>
<translation>git add -A</translation> <translation>git add -A</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="335" /> <location filename="../src/MainWindow.cpp" line="347" />
<location filename="../src/MainWindow.cpp" line="1251" /> <location filename="../src/MainWindow.cpp" line="1263" />
<location filename="../src/MainWindow.cpp" line="1258" /> <location filename="../src/MainWindow.cpp" line="1270" />
<location filename="../src/MainWindow.cpp" line="1262" /> <location filename="../src/MainWindow.cpp" line="1274" />
<location filename="../src/MainWindow.cpp" line="1338" /> <location filename="../src/MainWindow.cpp" line="1350" />
<source>提交</source> <source>提交</source>
<translation>Commit</translation> <translation>Commit</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="335" /> <location filename="../src/MainWindow.cpp" line="347" />
<source>把暂存区的内容提交</source> <source>把暂存区的内容提交</source>
<translation>Commit the staged changes</translation> <translation>Commit the staged changes</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="369" /> <location filename="../src/MainWindow.cpp" line="381" />
<location filename="../src/MainWindow.cpp" line="827" /> <location filename="../src/MainWindow.cpp" line="839" />
<source>文件</source> <source>文件</source>
<translation>File</translation> <translation>File</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="373" /> <location filename="../src/MainWindow.cpp" line="385" />
<location filename="../src/MainWindow.cpp" line="832" /> <location filename="../src/MainWindow.cpp" line="844" />
<source>最近打开</source> <source>最近打开</source>
<translation>Recent Files</translation> <translation>Recent Files</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="381" /> <location filename="../src/MainWindow.cpp" line="393" />
<location filename="../src/MainWindow.cpp" line="828" /> <location filename="../src/MainWindow.cpp" line="840" />
<source>编辑</source> <source>编辑</source>
<translation>Edit</translation> <translation>Edit</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="391" /> <location filename="../src/MainWindow.cpp" line="403" />
<location filename="../src/MainWindow.cpp" line="829" /> <location filename="../src/MainWindow.cpp" line="841" />
<source>视图</source> <source>视图</source>
<translation>View</translation> <translation>View</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="402" /> <location filename="../src/MainWindow.cpp" line="414" />
<location filename="../src/MainWindow.cpp" line="833" /> <location filename="../src/MainWindow.cpp" line="845" />
<source>主题</source> <source>主题</source>
<translation>Theme</translation> <translation>Theme</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="410" /> <location filename="../src/MainWindow.cpp" line="422" />
<location filename="../src/MainWindow.cpp" line="863" /> <location filename="../src/MainWindow.cpp" line="875" />
<source>6:00–18:00 使用浅色,其余时间使用深色</source> <source>6:00–18:00 使用浅色,其余时间使用深色</source>
<translation>Light from 6:00 to 18:00, dark the rest of the day</translation> <translation>Light from 6:00 to 18:00, dark the rest of the day</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="428" /> <location filename="../src/MainWindow.cpp" line="440" />
<location filename="../src/MainWindow.cpp" line="835" /> <location filename="../src/MainWindow.cpp" line="847" />
<source>语言</source> <source>语言</source>
<translation>Language</translation> <translation>Language</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="445" /> <location filename="../src/MainWindow.cpp" line="457" />
<location filename="../src/MainWindow.cpp" line="830" /> <location filename="../src/MainWindow.cpp" line="842" />
<source>格式</source> <source>格式</source>
<translation>Format</translation> <translation>Format</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="446" /> <location filename="../src/MainWindow.cpp" line="458" />
<location filename="../src/MainWindow.cpp" line="834" /> <location filename="../src/MainWindow.cpp" line="846" />
<source>标题</source> <source>标题</source>
<translation>Heading</translation> <translation>Heading</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="453" /> <location filename="../src/MainWindow.cpp" line="465" />
<location filename="../src/MainWindow.cpp" line="831" /> <location filename="../src/MainWindow.cpp" line="843" />
<source>帮助</source> <source>帮助</source>
<translation>Help</translation> <translation>Help</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="454" /> <location filename="../src/MainWindow.cpp" line="466" />
<location filename="../src/MainWindow.cpp" line="870" /> <location filename="../src/MainWindow.cpp" line="882" />
<location filename="../src/MainWindow.cpp" line="900" /> <location filename="../src/MainWindow.cpp" line="912" />
<source>关于 VoiletMark</source> <source>关于 VoiletMark</source>
<translation>About VoiletMark</translation> <translation>About VoiletMark</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="465" /> <location filename="../src/MainWindow.cpp" line="477" />
<location filename="../src/MainWindow.cpp" line="874" /> <location filename="../src/MainWindow.cpp" line="886" />
<source>显示 / 隐藏文件夹侧栏(Ctrl+B)</source> <source>显示 / 隐藏文件夹侧栏(Ctrl+B)</source>
<translation>Show / hide the folder sidebar (Ctrl+B)</translation> <translation>Show / hide the folder sidebar (Ctrl+B)</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="473" /> <location filename="../src/MainWindow.cpp" line="485" />
<location filename="../src/MainWindow.cpp" line="877" /> <location filename="../src/MainWindow.cpp" line="889" />
<source>源代码模式:关闭语法高亮与行号(Ctrl+Shift+M)</source> <source>源代码模式:关闭语法高亮与行号(Ctrl+Shift+M)</source>
<translation>Source mode: turn off highlighting and line numbers (Ctrl+Shift+M)</translation> <translation>Source mode: turn off highlighting and line numbers (Ctrl+Shift+M)</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="553" /> <location filename="../src/MainWindow.cpp" line="565" />
<location filename="../src/MainWindow.cpp" line="668" /> <location filename="../src/MainWindow.cpp" line="680" />
<source>未命名</source> <source>未命名</source>
<translation>Untitled</translation> <translation>Untitled</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="602" /> <location filename="../src/MainWindow.cpp" line="614" />
<source>打开 Markdown 文件</source> <source>打开 Markdown 文件</source>
<translation>Open Markdown File</translation> <translation>Open Markdown File</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="603" /> <location filename="../src/MainWindow.cpp" line="615" />
<source>Markdown 文件 (*.md *.markdown *.mdown *.mkd);;文本文件 (*.txt);;所有文件 (*)</source> <source>Markdown 文件 (*.md *.markdown *.mdown *.mkd);;文本文件 (*.txt);;所有文件 (*)</source>
<translation>Markdown files (*.md *.markdown *.mdown *.mkd);;Text files (*.txt);;All files (*)</translation> <translation>Markdown files (*.md *.markdown *.mdown *.mkd);;Text files (*.txt);;All files (*)</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="620" /> <location filename="../src/MainWindow.cpp" line="632" />
<source>无法打开文件</source> <source>无法打开文件</source>
<translation>Cannot Open File</translation> <translation>Cannot Open File</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="621" /> <location filename="../src/MainWindow.cpp" line="633" />
<source>读取「%1」失败:%2</source> <source>读取「%1」失败:%2</source>
<translation>Could not read "%1": %2</translation> <translation>Could not read "%1": %2</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="655" /> <location filename="../src/MainWindow.cpp" line="667" />
<source>另存为</source> <source>另存为</source>
<translation>Save As</translation> <translation>Save As</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="656" /> <location filename="../src/MainWindow.cpp" line="668" />
<source>Markdown 文件 (*.md);;文本文件 (*.txt);;所有文件 (*)</source> <source>Markdown 文件 (*.md);;文本文件 (*.txt);;所有文件 (*)</source>
<translation>Markdown files (*.md);;Text files (*.txt);;All files (*)</translation> <translation>Markdown files (*.md);;Text files (*.txt);;All files (*)</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="673" /> <location filename="../src/MainWindow.cpp" line="685" />
<source>导出 PDF</source> <source>导出 PDF</source>
<translation>Export PDF</translation> <translation>Export PDF</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="674" /> <location filename="../src/MainWindow.cpp" line="686" />
<source>PDF 文件 (*.pdf)</source> <source>PDF 文件 (*.pdf)</source>
<translation>PDF files (*.pdf)</translation> <translation>PDF files (*.pdf)</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="693" /> <location filename="../src/MainWindow.cpp" line="705" />
<source>导出失败</source> <source>导出失败</source>
<translation>Export Failed</translation> <translation>Export Failed</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="694" /> <location filename="../src/MainWindow.cpp" line="706" />
<source>没能写出「%1」,换个位置再试一次。</source> <source>没能写出「%1」,换个位置再试一次。</source>
<translation>Could not write "%1". Try another location.</translation> <translation>Could not write "%1". Try another location.</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="698" /> <location filename="../src/MainWindow.cpp" line="710" />
<source>已导出 %1</source> <source>已导出 %1</source>
<translation>Exported to %1</translation> <translation>Exported to %1</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="713" />
<location filename="../src/MainWindow.cpp" line="720" />
<location filename="../src/MainWindow.cpp" line="725" /> <location filename="../src/MainWindow.cpp" line="725" />
<location filename="../src/MainWindow.cpp" line="732" />
<location filename="../src/MainWindow.cpp" line="737" />
<source>无法保存文件</source> <source>无法保存文件</source>
<translation>Cannot Save File</translation> <translation>Cannot Save File</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="714" /> <location filename="../src/MainWindow.cpp" line="726" />
<source>写入「%1」失败:%2</source> <source>写入「%1」失败:%2</source>
<translation>Could not write "%1": %2</translation> <translation>Could not write "%1": %2</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="721" /> <location filename="../src/MainWindow.cpp" line="733" />
<source>写入「%1」时发生错误。</source> <source>写入「%1」时发生错误。</source>
<translation>An error occurred while writing "%1".</translation> <translation>An error occurred while writing "%1".</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="726" /> <location filename="../src/MainWindow.cpp" line="738" />
<source>提交「%1」失败:%2</source> <source>提交「%1」失败:%2</source>
<translation>Could not commit "%1": %2</translation> <translation>Could not commit "%1": %2</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="734" /> <location filename="../src/MainWindow.cpp" line="746" />
<source>已保存 %1</source> <source>已保存 %1</source>
<translation>Saved to %1</translation> <translation>Saved to %1</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="744" /> <location filename="../src/MainWindow.cpp" line="756" />
<source>VoiletMark</source> <source>VoiletMark</source>
<translation>VoiletMark</translation> <translation>VoiletMark</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="745" /> <location filename="../src/MainWindow.cpp" line="757" />
<source>「%1」有未保存的修改,是否保存?</source> <source>「%1」有未保存的修改,是否保存?</source>
<translation>"%1" has unsaved changes. Save them?</translation> <translation>"%1" has unsaved changes. Save them?</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="769" /> <location filename="../src/MainWindow.cpp" line="781" />
<source>%1[*] — VoiletMark</source> <source>%1[*] — VoiletMark</source>
<translation>%1[*] — VoiletMark</translation> <translation>%1[*] — VoiletMark</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="788" /> <location filename="../src/MainWindow.cpp" line="800" />
<source>行 %1,列 %2</source> <source>行 %1,列 %2</source>
<translation>Line %1, Col %2</translation> <translation>Line %1, Col %2</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="790" /> <location filename="../src/MainWindow.cpp" line="802" />
<source> 已选 %1 字</source> <source> 已选 %1 字</source>
<translation> %1 selected</translation> <translation> %1 selected</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="791" /> <location filename="../src/MainWindow.cpp" line="803" />
<source> %1 字</source> <source> %1 字</source>
<translation> %1 chars</translation> <translation> %1 chars</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="904" /> <location filename="../src/MainWindow.cpp" line="916" />
<source>&lt;h3&gt;VoiletMark %1&lt;/h3&gt;&lt;p&gt;一个轻量的跨平台 Markdown 编辑器。&lt;/p&gt;&lt;p&gt;基于 Qt %2 与 C++17 构建。&lt;/p&gt;</source> <source>&lt;h3&gt;VoiletMark %1&lt;/h3&gt;&lt;p&gt;一个轻量的跨平台 Markdown 编辑器。&lt;/p&gt;&lt;p&gt;基于 Qt %2 与 C++17 构建。&lt;/p&gt;</source>
<translation>&lt;h3&gt;VoiletMark %1&lt;/h3&gt;&lt;p&gt;A lightweight cross-platform Markdown editor.&lt;/p&gt;&lt;p&gt;Built with Qt %2 and C++17.&lt;/p&gt;</translation> <translation>&lt;h3&gt;VoiletMark %1&lt;/h3&gt;&lt;p&gt;A lightweight cross-platform Markdown editor.&lt;/p&gt;&lt;p&gt;Built with Qt %2 and C++17.&lt;/p&gt;</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="939" /> <location filename="../src/MainWindow.cpp" line="951" />
<source>(暂无记录)</source> <source>(暂无记录)</source>
<translation>(none)</translation> <translation>(none)</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="952" /> <location filename="../src/MainWindow.cpp" line="964" />
<source>清空列表</source> <source>清空列表</source>
<translation>Clear List</translation> <translation>Clear List</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="962" /> <location filename="../src/MainWindow.cpp" line="974" />
<source>打开文件夹</source> <source>打开文件夹</source>
<translation>Open Folder</translation> <translation>Open Folder</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1019" /> <location filename="../src/MainWindow.cpp" line="1031" />
<source>文件 → 打开文件夹…</source> <source>文件 → 打开文件夹…</source>
<translation>File → Open Folder…</translation> <translation>File → Open Folder…</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1055" /> <location filename="../src/MainWindow.cpp" line="1067" />
<source>(没有 Markdown 文件)</source> <source>(没有 Markdown 文件)</source>
<translation>(no Markdown files)</translation> <translation>(no Markdown files)</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1187" /> <location filename="../src/MainWindow.cpp" line="1199" />
<source>正在%1…</source> <source>正在%1…</source>
<translation>%1…</translation> <translation>%1…</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1197" /> <location filename="../src/MainWindow.cpp" line="1209" />
<source>Git 操作失败</source> <source>Git 操作失败</source>
<translation>Git Operation Failed</translation> <translation>Git Operation Failed</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1198" /> <location filename="../src/MainWindow.cpp" line="1210" />
<source>%1失败: <source>%1失败:
%2</source> %2</source>
@@ -463,64 +463,64 @@
%2</translation> %2</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1199" /> <location filename="../src/MainWindow.cpp" line="1211" />
<source>(没有输出)</source> <source>(没有输出)</source>
<translation>(no output)</translation> <translation>(no output)</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1205" /> <location filename="../src/MainWindow.cpp" line="1217" />
<source>%1完成</source> <source>%1完成</source>
<translation>%1 finished</translation> <translation>%1 finished</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1252" /> <location filename="../src/MainWindow.cpp" line="1264" />
<source>暂存区是空的,先点「暂存」把所有改动加进去。</source> <source>暂存区是空的,先点「暂存」把所有改动加进去。</source>
<translation>Nothing is staged yet. Click "Stage" first to add all changes.</translation> <translation>Nothing is staged yet. Click "Stage" first to add all changes.</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1258" /> <location filename="../src/MainWindow.cpp" line="1270" />
<source>提交说明:</source> <source>提交说明:</source>
<translation>Commit message:</translation> <translation>Commit message:</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1270" /> <location filename="../src/MainWindow.cpp" line="1282" />
<source>添加到提交</source> <source>添加到提交</source>
<translation>Add to commit</translation> <translation>Add to commit</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1289" /> <location filename="../src/MainWindow.cpp" line="1301" />
<source>「%1」已经在 .gitignore 里了</source> <source>「%1」已经在 .gitignore 里了</source>
<translation>"%1" is already in .gitignore</translation> <translation>"%1" is already in .gitignore</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1295" /> <location filename="../src/MainWindow.cpp" line="1307" />
<source>忽略文件</source> <source>忽略文件</source>
<translation>Ignore File</translation> <translation>Ignore File</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1296" /> <location filename="../src/MainWindow.cpp" line="1308" />
<source>打不开 .gitignore:%1</source> <source>打不开 .gitignore:%1</source>
<translation>Cannot open .gitignore: %1</translation> <translation>Cannot open .gitignore: %1</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1303" /> <location filename="../src/MainWindow.cpp" line="1315" />
<source>已把 %1 写进 .gitignore</source> <source>已把 %1 写进 .gitignore</source>
<translation>Added %1 to .gitignore</translation> <translation>Added %1 to .gitignore</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1318" /> <location filename="../src/MainWindow.cpp" line="1330" />
<location filename="../src/MainWindow.cpp" line="1323" /> <location filename="../src/MainWindow.cpp" line="1335" />
<location filename="../src/MainWindow.cpp" line="1361" /> <location filename="../src/MainWindow.cpp" line="1373" />
<source>删除远端</source> <source>删除远端</source>
<translation>Delete from remote</translation> <translation>Delete from remote</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1319" /> <location filename="../src/MainWindow.cpp" line="1331" />
<source>「%1」没有被 git 跟踪,远端本来就没有它。</source> <source>「%1」没有被 git 跟踪,远端本来就没有它。</source>
<translation>"%1" is not tracked by git, so the remote never had it.</translation> <translation>"%1" is not tracked by git, so the remote never had it.</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1324" /> <location filename="../src/MainWindow.cpp" line="1336" />
<source>从仓库删除「%1」并推送到远端? <source>从仓库删除「%1」并推送到远端?
本地文件会保留,远端和别人 pull 下来的仓库里会删掉它。</source> 本地文件会保留,远端和别人 pull 下来的仓库里会删掉它。</source>
@@ -529,52 +529,52 @@
Your local file is kept, but the remote copy and everyone else's will be deleted.</translation> Your local file is kept, but the remote copy and everyone else's will be deleted.</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1328" /> <location filename="../src/MainWindow.cpp" line="1340" />
<source>删除并推送</source> <source>删除并推送</source>
<translation>Delete and push</translation> <translation>Delete and push</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1337" /> <location filename="../src/MainWindow.cpp" line="1349" />
<source>chore: 从仓库删除 %1</source> <source>chore: 从仓库删除 %1</source>
<translation>chore: remove %1 from repository</translation> <translation>chore: remove %1 from repository</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1356" /> <location filename="../src/MainWindow.cpp" line="1368" />
<source>添加</source> <source>添加</source>
<translation>Add</translation> <translation>Add</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1357" /> <location filename="../src/MainWindow.cpp" line="1369" />
<source>git add 这个文件</source> <source>git add 这个文件</source>
<translation>git add this file</translation> <translation>git add this file</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1358" /> <location filename="../src/MainWindow.cpp" line="1370" />
<source>忽略</source> <source>忽略</source>
<translation>Ignore</translation> <translation>Ignore</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1359" /> <location filename="../src/MainWindow.cpp" line="1371" />
<source>把路径写进 .gitignore(不改仓库里已跟踪的文件)</source> <source>把路径写进 .gitignore(不改仓库里已跟踪的文件)</source>
<translation>Add the path to .gitignore (does not untrack files already in the repo)</translation> <translation>Add the path to .gitignore (does not untrack files already in the repo)</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1362" /> <location filename="../src/MainWindow.cpp" line="1374" />
<source>git rm --cached 后提交并推送:远端删除,本地保留</source> <source>git rm --cached 后提交并推送:远端删除,本地保留</source>
<translation>git rm --cached, then commit and push: gone from the remote, kept locally</translation> <translation>git rm --cached, then commit and push: gone from the remote, kept locally</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1329" /> <location filename="../src/MainWindow.cpp" line="1341" />
<source>取消</source> <source>取消</source>
<translation>Cancel</translation> <translation>Cancel</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1335" /> <location filename="../src/MainWindow.cpp" line="1347" />
<source>从仓库移除</source> <source>从仓库移除</source>
<translation>Remove from repository</translation> <translation>Remove from repository</translation>
</message> </message>
<message> <message>
<location filename="../src/MainWindow.cpp" line="1352" /> <location filename="../src/MainWindow.cpp" line="1364" />
<source>打开</source> <source>打开</source>
<translation>Open</translation> <translation>Open</translation>
</message> </message>
@@ -582,23 +582,43 @@ Your local file is kept, but the remote copy and everyone else's will be deleted
<context> <context>
<name>MarkdownEditor</name> <name>MarkdownEditor</name>
<message> <message>
<location filename="../src/MarkdownEditor.cpp" line="561" /> <location filename="../src/MarkdownEditor.cpp" line="577" />
<location filename="../src/MarkdownEditor.cpp" line="675" /> <location filename="../src/MarkdownEditor.cpp" line="701" />
<source>已复制</source> <source>已复制</source>
<translation>Copied</translation> <translation>Copied</translation>
</message> </message>
<message> <message>
<location filename="../src/MarkdownEditor.cpp" line="561" /> <location filename="../src/MarkdownEditor.cpp" line="577" />
<location filename="../src/MarkdownEditor.cpp" line="675" /> <location filename="../src/MarkdownEditor.cpp" line="701" />
<source>复制</source> <source>复制</source>
<translation>Copy</translation> <translation>Copy</translation>
</message> </message>
<message> <message>
<location filename="../src/MarkdownEditor.cpp" line="606" /> <location filename="../src/MarkdownEditor.cpp" line="632" />
<location filename="../src/MarkdownEditor.cpp" line="617" /> <location filename="../src/MarkdownEditor.cpp" line="643" />
<source>纯文本</source> <source>纯文本</source>
<translation>Plain text</translation> <translation>Plain text</translation>
</message> </message>
<message>
<location filename="../src/MarkdownEditor.cpp" line="1095" />
<source>插入行</source>
<translation>Insert row</translation>
</message>
<message>
<location filename="../src/MarkdownEditor.cpp" line="1110" />
<source>删除行</source>
<translation>Delete row</translation>
</message>
<message>
<location filename="../src/MarkdownEditor.cpp" line="1120" />
<source>插入列</source>
<translation>Insert column</translation>
</message>
<message>
<location filename="../src/MarkdownEditor.cpp" line="1135" />
<source>删除列</source>
<translation>Delete column</translation>
</message>
</context> </context>
<context> <context>
<name>QObject</name> <name>QObject</name>