Engine: - organize.rs: build_document(plan) core — insert/delete/rotate/crop/extract/merge/split - watermark.rs: watermark + header/footer via PdfPages::watermark, CID Unicode fonts - qpdf.rs: QPDF CLI wrapper — repair corrupt files, re-encrypt after edits, ensure_openable - edit.rs: MOAT — list_objects + apply_edits (SetText VN, Transform, Delete, Add/ReplaceImage) - Tests: organize/watermark/qpdf_safety/edit roundtrip — 43/43 engine tests green UI (Tauri): "Tổ chức trang" mode (grid + drag-reorder + multi-select), "Sửa nội dung" mode (WYSIWYG object overlay, edit-in-place), global undo/redo, robust file open. Corpus: add encrypted.pdf + corrupt-truncated.pdf fixtures. Docs: mark Phase 1-4 done in roadmap; document QPDF setup + engine module layout in 05-dev-setup; add 10-13 phase summaries & user-test checklists; README status.
124 lines
6.5 KiB
HTML
124 lines
6.5 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="vi">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>FoFreeXit</title>
|
||
<link rel="stylesheet" href="styles.css" />
|
||
</head>
|
||
<body>
|
||
<header class="toolbar">
|
||
<strong class="brand">FoFreeXit</strong>
|
||
<span class="phase">Phase 1 · Viewer</span>
|
||
<button id="openBtn" title="Mở file PDF">📂 Mở</button>
|
||
<span class="sep"></span>
|
||
<button id="pagePrev" title="Trang trước (Page Up)">▲</button>
|
||
<input id="pageInput" class="pagenum" type="text" inputmode="numeric" title="Đến trang…" />
|
||
<span class="pageof">/ <span id="pageTotal">—</span></span>
|
||
<button id="pageNext" title="Trang sau (Page Down)">▼</button>
|
||
<span class="sep"></span>
|
||
<button id="zoomOut" title="Thu nhỏ (Ctrl+-)">−</button>
|
||
<select id="zoomSelect" class="zoom" title="Mức zoom"></select>
|
||
<button id="zoomIn" title="Phóng to (Ctrl++)">+</button>
|
||
<button id="zoomFit" title="Vừa bề rộng">Vừa rộng</button>
|
||
<button id="zoomFitPage" title="Vừa trang">Vừa trang</button>
|
||
<span class="sep"></span>
|
||
<input id="searchBox" type="search" placeholder="Tìm trong tài liệu… (Ctrl+F)" autofocus />
|
||
<label class="searchopt" title="Phân biệt hoa/thường"><input id="searchCase" type="checkbox" />Aa</label>
|
||
<button id="searchPrev" title="Kết quả trước (Shift+Enter)">◀</button>
|
||
<span id="searchCount" class="searchcount">—</span>
|
||
<button id="searchNext" title="Kết quả sau (Enter)">▶</button>
|
||
<span class="sep"></span>
|
||
<button id="copyPage" title="Copy text trang hiện tại">⧉ Copy</button>
|
||
<span class="sep"></span>
|
||
<button id="undoBtn" title="Hoàn tác (Ctrl+Z)" disabled>↶ Hoàn tác</button>
|
||
<button id="redoBtn" title="Làm lại (Ctrl+Y)" disabled>↷ Làm lại</button>
|
||
<span class="sep"></span>
|
||
<button id="organizeModeBtn" title="Tổ chức trang">🗂 Tổ chức trang</button>
|
||
<button id="editModeBtn" title="Sửa nội dung trang">✏️ Sửa nội dung</button>
|
||
<div class="spacer"></div>
|
||
<span id="status" class="status"></span>
|
||
</header>
|
||
|
||
<div id="annobar" class="annobar">
|
||
<span class="annolabel">Chú thích:</span>
|
||
<button class="atool" data-tool="highlight" title="Tô sáng (kéo vùng)">🖍️ Tô sáng</button>
|
||
<button class="atool" data-tool="underline" title="Gạch chân">U̲ Gạch chân</button>
|
||
<button class="atool" data-tool="strikeout" title="Gạch ngang">S̶ Gạch ngang</button>
|
||
<button class="atool" data-tool="square" title="Khung chữ nhật">▭ Khung</button>
|
||
<button class="atool" data-tool="freetext" title="Hộp văn bản">🅣 Text box</button>
|
||
<button class="atool" data-tool="note" title="Ghi chú dán">📌 Ghi chú</button>
|
||
<button class="atool" data-tool="crop" title="Crop trang">✂️ Crop</button>
|
||
<span class="sep"></span>
|
||
<button id="annotColorBtn" class="atool" title="Màu chú thích"><span class="sw" id="annotSw"></span> Màu</button>
|
||
<span class="spacer"></span>
|
||
<span id="annotHint" class="status"></span>
|
||
<button id="saveAnnots" disabled>💾 Lưu chú thích (<span id="annotCount">0</span>)</button>
|
||
</div>
|
||
|
||
<div id="organizeBar" class="organizebar hidden">
|
||
<span class="annolabel">Tổ chức trang:</span>
|
||
<button id="orgInsert" title="Chèn trang">➕ Chèn</button>
|
||
<button id="orgDelete" title="Xoá trang đã chọn (Delete)">🗑 Xoá</button>
|
||
<button id="orgRotateL" title="Xoay trái">↺ Xoay trái</button>
|
||
<button id="orgRotateR" title="Xoay phải">↻ Xoay phải</button>
|
||
<button id="orgExtract" title="Trích trang đã chọn">📤 Trích</button>
|
||
<button id="orgReplace" title="Thay trang đã chọn">🔁 Thay</button>
|
||
<span class="sep"></span>
|
||
<button id="orgMerge" title="Trộn nhiều file PDF">🔀 Trộn file</button>
|
||
<button id="orgSplit" title="Tách thành nhiều file">✂ Tách file</button>
|
||
<button id="orgWatermark" title="Thêm watermark">💧 Watermark</button>
|
||
<button id="orgHeaderFooter" title="Thêm header/footer">📋 Header/Footer</button>
|
||
<span class="spacer"></span>
|
||
<span id="organizeHint" class="status"></span>
|
||
<button id="orgSave" disabled>💾 Lưu thay đổi tổ chức trang</button>
|
||
</div>
|
||
|
||
<div id="editBar" class="editbar hidden">
|
||
<span class="annolabel">Sửa nội dung:</span>
|
||
<button id="edAddText" title="Thêm chữ — bấm rồi click lên trang">🆎 Thêm chữ</button>
|
||
<button id="edAddImage" title="Thêm ảnh — chọn ảnh rồi click lên trang">🖼 Thêm ảnh</button>
|
||
<button id="edDelete" title="Xoá đối tượng đang chọn (Delete)" disabled>🗑 Xoá</button>
|
||
<button id="edReplaceImage" title="Thay ảnh đang chọn" disabled>🔁 Thay ảnh</button>
|
||
<span class="sep"></span>
|
||
<label class="ed-prop">Cỡ chữ <input id="edFontSize" type="number" min="1" max="400" disabled></label>
|
||
<button id="edColorBtn" class="atool" title="Màu chữ" disabled><span class="sw" id="edSw"></span> Màu</button>
|
||
<span class="spacer"></span>
|
||
<span id="editHint" class="status"></span>
|
||
<button id="edSave" disabled>💾 Lưu thay đổi nội dung</button>
|
||
</div>
|
||
|
||
<div class="body">
|
||
<aside id="sidebar" class="sidebar">
|
||
<div class="tabs">
|
||
<button id="tabThumbs" class="tab active">Thumbnails</button>
|
||
<button id="tabOutline" class="tab">Outline</button>
|
||
<button id="tabComments" class="tab">Chú thích</button>
|
||
</div>
|
||
<div id="thumbs" class="panel thumbs"></div>
|
||
<div id="outline" class="panel outline hidden"></div>
|
||
<div id="comments" class="panel comments hidden"></div>
|
||
</aside>
|
||
|
||
<main id="viewport" class="viewport">
|
||
<div id="pages" class="pages"></div>
|
||
</main>
|
||
|
||
<main id="organizeGrid" class="organize-grid hidden"></main>
|
||
|
||
<main id="editStage" class="edit-stage hidden">
|
||
<div id="editPageWrap" class="edit-page-wrap">
|
||
<img id="editImg" class="edit-img" alt="trang đang sửa"/>
|
||
<div id="editOverlay" class="edit-overlay"></div>
|
||
</div>
|
||
</main>
|
||
</div>
|
||
|
||
<div id="modalOverlay" class="modal-overlay hidden">
|
||
<div id="modalBox" class="modal-box"></div>
|
||
</div>
|
||
|
||
<script src="main.js"></script>
|
||
</body>
|
||
</html>
|