Files
work-secretfile-selfcheck/UmiOCR-data/qt_res/qml/TabPages/BatchDOC/BatchDOC.qml

312 lines
10 KiB
QML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ==================================================
// =============== 功能页:批量文档处理 ===============
// ==================================================
import QtQuick 2.15
import QtQuick.Controls 2.15
import ".."
import "../../Widgets"
import "../../Widgets/ResultLayout"
import "../../Widgets/IgnoreArea"
/* 文档参数:
path 路径
pages 页数显示
state 状态显示
page_count 总页数
range_start 范围开始
range_end 范围结束
is_encrypted 需要密码
is_authenticate 密码正确
password 密码
*/
TabPage {
id: tabPage
// ========================= 【逻辑】 =========================
property string msnID: "" // 当前任务ID
// 异步加载一批文档路径
function addDocs(paths) {
if(paths.length <= 0) return
const isRecurrence = configsComp.getValue("mission.recurrence")
qmlapp.asynFilesLoader.run(paths,"doc",isRecurrence,onAddDocs)
}
// 完毕后,将合法表格加入表格
function onAddDocs(docs) {
if(docs.length <= 0) return
let encryptedCount = 0
for(let i in docs) {
const info = docs[i]
filesTableView.add({
// 显示:路径,状态,页范围
path: info.path,
pages: `${info.page_count}`, // 如果范围为整本,只显示总页数。否则显示 起始-结束
state: info.is_encrypted ? qsTr("加密") : "" ,
// 数据
page_count: info.page_count,
range_start: 1,
range_end: info.page_count,
is_encrypted: info.is_encrypted, // 有密码
is_authenticate: !info.is_encrypted, // 已解密(密码正确)
password: "",
})
if(info.is_encrypted) encryptedCount++
}
if(encryptedCount > 0) {
qmlapp.popup.simple(qsTr("%1个加密文档").arg(encryptedCount),
qsTr("请点击文件名填写密码"))
}
}
// 运行文档任务
function docStart() {
const fileCount = filesTableView.rowCount
if(fileCount <= 0) {
ctrlPanel.stopFinished()
return
}
// 获取信息
const docs = filesTableView.getColumnsValues([
"path","range_start", "range_end", "page_count", "is_encrypted", "is_authenticate", "password"])
// 第1次遍历检查密码填写
for(let i = 0; i < fileCount; i++) {
const d = docs[i]
if(d.is_encrypted && !d.is_authenticate) {
qmlapp.popup.message(qsTr("文档已加密"), qsTr("【%1】\n请点击文档名设置密码").arg(d.path), "warning")
ctrlPanel.stopFinished()
return
}
}
// 第2次遍历刷新信息
let allPages = 0 // 页总数
for(let i = 0; i < fileCount; i++) {
const d = docs[i]
allPages += d.range_end - d.range_start + 1
filesTableView.setProperty(d.path, "state", qsTr("排队"))
}
// 若tabPanel面板的下标没有变化过则切换到记录页
if(tabPanel.indexChangeNum < 2)
tabPanel.currentIndex = 1
// 任务进度 开始计时
ctrlPanel.runFinished(allPages)
// 提交任务
const argd = configsComp.getValueDict()
tabPage.callPy("msnDocs", docs, argd)
}
// 停止文档任务
function docStop() {
tabPage.callPy("msnStop")
// 刷新表格,清空未执行的任务的状态
let msnLength = filesTableView.rowCount
for(let i = 0; i < msnLength; i++) {
const row = filesTableView.get(i)
const s = row.state
if(s.length > 0 && s[0] !== "√" && s[0] !== "×") {
filesTableView.setProperty(i, "state", "")
}
}
ctrlPanel.stopFinished()
}
// 文件表格中单击文档
function onClickDoc(index) {
if(ctrlPanel.state_ !== "stop") return
const info = filesTableView.get(index)
if(Object.keys(info).length > 0)
previewDoc.show(info)
}
// 关闭页面
function closePage() {
if(ctrlPanel.state_ !== "stop") {
const argd = { yesText: qsTr("依然关闭") }
const callback = (flag)=>{
if(flag) {
docStop()
delPage()
}
}
qmlapp.popup.dialog("", qsTr("任务正在进行中。\n要结束任务并关闭页面吗"), callback, "warning", argd)
}
else {
delPage()
}
}
// ========================= 【python调用qml】 =========================
// 准备开始处理一个文档
function onDocStart(path) {
// 刷新表格显示
const d = filesTableView.get(path)
let state = `0/${d.range_end - d.range_start + 1}`
filesTableView.setProperty(path, "state", state)
}
// 获取一个文档的一页的结果
function onDocGet(path, page, res) {
// 刷新单个文档的信息
const d = filesTableView.get(path)
const state = `${page - d.range_start + 1}/${d.range_end - d.range_start + 1}`
filesTableView.setProperty(path, "state", state)
// 提取文字,添加到结果表格
const title = path2name(path)
res.title = `${title} - ${page}`
resultsTableView.addOcrResult(res)
ctrlPanel.msnStep(1)
}
// 一个文档处理完毕。 isAll==true 时所有文档处理完毕。
function onDocEnd(path, msg, isAll) {
const errTitle = qsTr("文档识别异常")
// 成功结束
if(msg.startsWith("[Success]")) {
filesTableView.setProperty(path, "state", "√")
msg = ""
}
// 单个文档任务失败,总体未结束
else if(!isAll) {
filesTableView.setProperty(path, "state", "× "+ qsTr("失败"))
qmlapp.popup.simple(errTitle, msg)
}
// 所有文档处理完毕
if(isAll) {
const simpleType = configsComp.getValue("other.simpleNotificationType")
qmlapp.popup.simple(qsTr("批量识别完成"), "", simpleType)
if(msg) // 如果有异常,则弹窗
qmlapp.popup.message(errTitle, msg, "error")
ctrlPanel.stopFinished()
// 任务完成后续操作
qmlapp.globalConfigs.utilsDicts.postTaskHardwareCtrl(
configsComp.getValue("postTaskActions.system")
)
}
}
// 路径转文件名
function path2name(path) {
const parts = path.split("/")
return parts[parts.length - 1]
}
// ========================= 【布局】 =========================
// 配置
configsComp: BatchDOCConfigs {}
// 主区域:可切换双栏面板
DoubleSwitchableLayout {
id: doubleLayout
saveKey: "BatchDOC_1"
anchors.fill: parent
// 面板A控制板+文件表格
itemA: Panel {
anchors.fill: parent
// 上方控制板
MissionCtrlPanel {
id: ctrlPanel
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: size_.spacing
height: size_.line * 2
onRunClicked: tabPage.docStart()
onPauseClicked: {
tabPage.callPy("msnPause")
pauseFinished()
}
onResumeClicked: {
tabPage.callPy("msnResume")
resumeFinished()
}
onStopClicked: tabPage.docStop()
}
// 下方文件表格
FilesTableView {
id: filesTableView
anchors.top: ctrlPanel.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: size_.spacing
anchors.topMargin: size_.smallSpacing
headers: [
{key: "path", title: qsTr("文档"), left: true, display: path2name,
btn: true, onClicked:onClickDoc},
{key: "state", title: qsTr("状态"), btn: true, onClicked:onClickDoc},
{key: "pages", title: qsTr("页数"), btn: true, onClicked:onClickDoc},
]
openBtnText: qsTr("打开文档")
clearBtnText: qsTr("清空")
defaultTips: qsTr("拖入文档或文件夹")
fileDialogTitle: qsTr("请选择文档")
fileDialogNameFilters: [qsTr("文档")+" (*.pdf *.xps *.epub *.mobi *.fb2 *.cbz)"]
isLock: ctrlPanel.state_ !== "stop"
onAddPaths: {
tabPage.addDocs(paths)
}
}
}
// 面板B文字输出 & 设置
itemB: Panel {
anchors.fill: parent
// 配置项控制板
TabPanel {
id: tabPanel
anchors.fill: parent
anchors.margins: size_.spacing
isMenuTop: doubleLayout.isRow // 左右布局时,菜单在顶部;上下布局时菜单在底部
menuHeight: size_.line * 2
// 结果面板
ResultsTableView {
id: resultsTableView
anchors.fill: parent
visible: false
}
tabsModel: [
{
"key": "configs",
"title": qsTr("设置"),
"component": configsComp.panelComponent,
},
{
"key": "ocrResult",
"title": qsTr("记录"),
"component": resultsTableView,
},
]
}
}
}
// 鼠标拖入文档
DropArea_ {
id: "addDocsDropArea"
anchors.fill: parent
callback: tabPage.addDocs
}
// 预览面板
PreviewDoc {
id: previewDoc
anchors.fill: parent
configsComp: tabPage.configsComp
updateInfo: (path, info) => {
let infoA = filesTableView.get(path)
Object.assign(infoA, info)
filesTableView.set(path, infoA)
}
}
}