Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion 3rdparty/deepin-pdfium/include/dpdfdoc.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

Expand Down Expand Up @@ -111,6 +111,13 @@ class DPdfDoc : public QObject
*/
QString label(int index) const;

/**
* @brief 获取 PDF 文档的永久标识符(Trailer /ID 的第一个值)
* 此 ID 在文档创建时生成,改名/移动不变,可用于唯一标识同一文档
* @return 永久 ID 的十六进制字符串,获取失败返回空串
*/
QString fileIdentifier() const;

/**
* @brief 保存到当前文件
* @return
Expand Down
23 changes: 23 additions & 0 deletions 3rdparty/deepin-pdfium/src/dpdfdoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ bool DPdfDoc::saveAs(const QString &filePath)
bool result = FPDF_SaveAsCopy(reinterpret_cast<FPDF_DOCUMENT>(d_func()->m_docHandler), &write, FPDF_NO_INCREMENTAL);
locker.unlock();

saveWriter.flush(); // Flush user buffer to kernel buffer
fsync(saveWriter.handle()); // Sync kernel buffer to disk
saveWriter.close();

return result;
Expand All @@ -349,6 +351,27 @@ int DPdfDoc::pageCount() const
return d_func()->m_pageCount;
}

QString DPdfDoc::fileIdentifier() const
{
FPDF_DOCUMENT doc = reinterpret_cast<FPDF_DOCUMENT>(d_func()->m_docHandler);
if (!doc)
return QString();

// 先查询所需缓冲区大小
unsigned long len = FPDF_GetFileIdentifier(doc, FILEIDTYPE_PERMANENT, nullptr, 0);
if (len == 0)
return QString();

QByteArray buf(len, '\0');
FPDF_GetFileIdentifier(doc, FILEIDTYPE_PERMANENT, buf.data(), len);

// PDF /ID 是原始字节串(通常为 16 字节 MD5),非 UTF-8 文本
// 转为十六进制字符串,确保可打印、可存储、可比较
// len 包含末尾 NUL,buf.size()-1 为实际数据长度
QByteArray data = QByteArray::fromRawData(buf.constData(), buf.size() - 1);
return QString::fromLatin1(data.toHex());
}

DPdfDoc::Status DPdfDoc::status() const
{
return d_func()->m_status;
Expand Down
226 changes: 166 additions & 60 deletions reader/app/Database.cpp

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions reader/app/Database.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ class Database : public QObject
*/
int cleanupOrphanStates();

/**
* @brief flushToDisk
* 强制将数据库缓存数据刷写到磁盘,确保进程异常终止后数据不丢失
* 在关键数据(书签、阅读进度)保存后调用
*/
void flushToDisk();

/**
* @brief computeContentHash
* 计算文件前64KB内容的SHA256哈希
Expand Down
9 changes: 7 additions & 2 deletions reader/document/Model.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2023 -2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -224,6 +224,11 @@ class Document: public QObject
virtual bool saveAs(const QString &filePath) const = 0;
virtual Outline outline() const { return Outline(); } // LCOV_EXCL_LINE
virtual Properties properties() const = 0;
/**
* @brief 获取文档内置的唯一标识符(如 PDF 的 /ID)
* 用于在文件被移动/重命名后识别同一文档,返回空串表示无可用 ID
*/
virtual QString fileIdentifier() const { return QString(); }
};

class DocumentFactory
Expand Down
9 changes: 8 additions & 1 deletion reader/document/PDFModel.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2023 -2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -496,6 +496,13 @@ bool PDFDocument::save() const
return m_document->save();
}

QString PDFDocument::fileIdentifier() const
{
if (!m_document)
return QString();
return m_document->fileIdentifier();
}

bool PDFDocument::saveAs(const QString &filePath) const
{
qCInfo(appLog) << "Saving PDF document as:" << filePath;
Expand Down
6 changes: 4 additions & 2 deletions reader/document/PDFModel.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Copyright (C) 2019 ~ 2020 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// Copyright (C) 2019 - 2026 Uniontech Software Technology Co.,Ltd.
// SPDX-FileCopyrightText: 2023 -2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -118,6 +118,8 @@ class PDFDocument : public Document

Properties properties() const override;

QString fileIdentifier() const override;

static PDFDocument *loadDocument(const QString &filePath, const QString &password, deepin_reader::Document::Error &error);

private:
Expand Down
9 changes: 8 additions & 1 deletion reader/uiframe/SheetRenderer.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -254,6 +254,13 @@ bool SheetRenderer::save()
return success;
}

QString SheetRenderer::fileIdentifier() const
{
if (m_document == nullptr)
return QString();
return m_document->fileIdentifier();
}

void SheetRenderer::loadPageLable()
{
qCDebug(appLog) << "SheetRenderer::loadPageLable start";
Expand Down
7 changes: 6 additions & 1 deletion reader/uiframe/SheetRenderer.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

Expand Down Expand Up @@ -191,6 +191,11 @@ class SheetRenderer : public QObject
*/
bool save();

/**
* @brief 获取文档内置唯一标识符
*/
QString fileIdentifier() const;

/**
* @brief saveAs
* 另存为
Expand Down
Loading