Files
VoiletMark/src/ExportDialog.cpp
T
liyepan 2f8726ad47 fix: v0.5.1 —— 导出窗口适配屏幕、去掉实时预览字样、图标加底板
- 导出预览窗口按屏幕可用高度计算尺寸,底部的「保存 PDF…」不会再顶出屏幕
- 默认欢迎文档去掉「实时预览(下一版)」,换成已实现的导出 PDF
- logo 是黑字透明底,放深色任务栏里等于看不见;packaging/generate_icons.py
  给它垫白色圆角底板并输出 16–256 多尺寸 ico,窗口图标与 exe 图标统一使用
- 新增 packaging/generate_icons.py,便于换图后重新生成
- 文档与截图同步
2026-10-22 18:03:38 +08:00

112 lines
4.0 KiB
C++

#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();
}