From dd108b5c8a40b3cf4057b6df77bed88d54aad32f Mon Sep 17 00:00:00 2001 From: 87owo <85057800+87owo@users.noreply.github.com> Date: Tue, 22 Sep 2026 02:26:15 +0800 Subject: [PATCH] Add files via upload --- Interface/static/js/i18n.js | 57 ++++++++++++++++++++++--------------- Interface/static/js/main.js | 38 ++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 27 deletions(-) diff --git a/Interface/static/js/i18n.js b/Interface/static/js/i18n.js index 5aa11ab..d0a898e 100644 --- a/Interface/static/js/i18n.js +++ b/Interface/static/js/i18n.js @@ -120,8 +120,9 @@ window.AppI18n = { "col_class": "類別", "col_title": "標題", "col_repair": "修復項目", - "btn_select_all": "全選", - "ctx_open_loc": "打開檔案所在位置", + "btn_select_all": "全選", + "ctx_open_loc": "打開檔案所在位置", + "ctx_copy_cell": "複製當前欄位文字", "msg_too_many": "(資料過多,僅顯示前 {0} 筆以確保效能流暢)", "res_scan_comp": "掃描完成", "res_virus_det": "發現病毒", @@ -309,8 +310,9 @@ window.AppI18n = { "col_class": "类别", "col_title": "标题", "col_repair": "修复项目", - "btn_select_all": "全选", - "ctx_open_loc": "打开文件所在位置", + "btn_select_all": "全选", + "ctx_open_loc": "打开文件所在位置", + "ctx_copy_cell": "复制当前字段文本", "msg_too_many": "(数据过多,仅显示前 {0} 条以确保性能流畅)", "res_scan_comp": "扫描完成", "res_virus_det": "发现病毒", @@ -498,8 +500,9 @@ window.AppI18n = { "col_class": "Class", "col_title": "Title", "col_repair": "Repair Items", - "btn_select_all": "Select All", - "ctx_open_loc": "Open file location", + "btn_select_all": "Select All", + "ctx_open_loc": "Open file location", + "ctx_copy_cell": "Copy current field text", "msg_too_many": "(Too much data, showing only the top {0} records for performance)", "res_scan_comp": "Scan Completed", "res_virus_det": "Virus Detected", @@ -687,8 +690,9 @@ window.AppI18n = { "col_class": "クラス", "col_title": "タイトル", "col_repair": "修復項目", - "btn_select_all": "すべて選択", - "ctx_open_loc": "ファイルの場所を開く", + "btn_select_all": "すべて選択", + "ctx_open_loc": "ファイルの場所を開く", + "ctx_copy_cell": "現在のフィールドのテキストをコピー", "msg_too_many": "(データが多すぎるため、パフォーマンスを確保するために上位 {0} 件のみを表示します)", "res_scan_comp": "スキャン完了", "res_virus_det": "ウイルスを検出", @@ -876,8 +880,9 @@ window.AppI18n = { "col_class": "클래스", "col_title": "제목", "col_repair": "복구 항목", - "btn_select_all": "전체 선택", - "ctx_open_loc": "파일 위치 열기", + "btn_select_all": "전체 선택", + "ctx_open_loc": "파일 위치 열기", + "ctx_copy_cell": "현재 필드 텍스트 복사", "msg_too_many": "(데이터가 너무 많아 성능 유지를 위해 상위 {0}개만 표시합니다)", "res_scan_comp": "스캔 완료", "res_virus_det": "바이러스 발견", @@ -1065,8 +1070,9 @@ window.AppI18n = { "col_class": "Classe", "col_title": "Titre", "col_repair": "Éléments de réparation", - "btn_select_all": "Tout sélectionner", - "ctx_open_loc": "Ouvrir l'emplacement du fichier", + "btn_select_all": "Tout sélectionner", + "ctx_open_loc": "Ouvrir l'emplacement du fichier", + "ctx_copy_cell": "Copier le texte du champ actuel", "msg_too_many": "(Trop de données, affichage des {0} premiers enregistrements pour des raisons de performances)", "res_scan_comp": "Analyse terminée", "res_virus_det": "Virus détecté", @@ -1254,8 +1260,9 @@ window.AppI18n = { "col_class": "Clase", "col_title": "Título", "col_repair": "Elementos de reparación", - "btn_select_all": "Seleccionar todo", - "ctx_open_loc": "Abrir ubicación de archivo", + "btn_select_all": "Seleccionar todo", + "ctx_open_loc": "Abrir ubicación de archivo", + "ctx_copy_cell": "Copiar texto del campo actual", "msg_too_many": "(Demasiados datos, mostrando solo los primeros {0} registros para mantener el rendimiento)", "res_scan_comp": "Escaneo completado", "res_virus_det": "Virus detectado", @@ -1443,8 +1450,9 @@ window.AppI18n = { "col_class": "वर्ग", "col_title": "शीर्षक", "col_repair": "मरम्मत आइटम", - "btn_select_all": "सभी चुनें", - "ctx_open_loc": "फ़ाइल स्थान खोलें", + "btn_select_all": "सभी चुनें", + "ctx_open_loc": "फ़ाइल स्थान खोलें", + "ctx_copy_cell": "वर्तमान फ़ील्ड का टेक्स्ट कॉपी करें", "msg_too_many": "(बहुत अधिक डेटा, प्रदर्शन सुनिश्चित करने के लिए केवल शीर्ष {0} रिकॉर्ड दिखा रहा है)", "res_scan_comp": "स्कैन पूरा हुआ", "res_virus_det": "वायरस का पता चला", @@ -1632,8 +1640,9 @@ window.AppI18n = { "col_class": "الفئة", "col_title": "العنوان", "col_repair": "عناصر الإصلاح", - "btn_select_all": "تحديد الكل", - "ctx_open_loc": "فتح موقع الملف", + "btn_select_all": "تحديد الكل", + "ctx_open_loc": "فتح موقع الملف", + "ctx_copy_cell": "نسخ نص الحقل الحالي", "msg_too_many": "(بيانات كثيرة جدًا، يتم عرض أول {0} سجل فقط لضمان الأداء)", "res_scan_comp": "اكتمل الفحص", "res_virus_det": "تم اكتشاف فيروس", @@ -1821,8 +1830,9 @@ window.AppI18n = { "col_class": "Класс", "col_title": "Заголовок", "col_repair": "Элементы восстановления", - "btn_select_all": "Выбрать все", - "ctx_open_loc": "Открыть расположение файла", + "btn_select_all": "Выбрать все", + "ctx_open_loc": "Открыть расположение файла", + "ctx_copy_cell": "Копировать текст текущего поля", "msg_too_many": "(Слишком много данных, показаны только первые {0} записей для обеспечения производительности)", "res_scan_comp": "Сканирование завершено", "res_virus_det": "Обнаружен вирус", @@ -2010,8 +2020,9 @@ window.AppI18n = { "col_class": "Razred", "col_title": "Naslov", "col_repair": "Predmeti za popravilo", - "btn_select_all": "Izberi vse", - "ctx_open_loc": "Odpri mesto datoteke", + "btn_select_all": "Izberi vse", + "ctx_open_loc": "Odpri mesto datoteke", + "ctx_copy_cell": "Kopiraj besedilo trenutnega polja", "msg_too_many": "(Preveč podatkov, prikazanih je samo prvih {0} zapisov za zagotavljanje zmogljivosti)", "res_scan_comp": "Skeniranje končano", "res_virus_det": "Zaznan virus", @@ -2093,4 +2104,4 @@ window.AppI18n = { russian_switch: "ru", slovenian_switch: "sl" } -}; \ No newline at end of file +}; diff --git a/Interface/static/js/main.js b/Interface/static/js/main.js index f8cf518..f1d8b07 100644 --- a/Interface/static/js/main.js +++ b/Interface/static/js/main.js @@ -1090,19 +1090,44 @@ document.addEventListener('DOMContentLoaded', () => { const contextMenu = document.createElement('div'); contextMenu.className = 'custom-context-menu'; - contextMenu.innerHTML = `
`; + contextMenu.innerHTML = ` +
+
`; document.body.appendChild(contextMenu); let ctxTarget = null; + let ctxCellText = null; + + const copyTextToClipboard = async (text) => { + if (navigator.clipboard?.writeText) { + try { + await navigator.clipboard.writeText(text); + return; + } catch (e) {} + } + + const textarea = document.createElement('textarea'); + textarea.value = text; + textarea.style.position = 'fixed'; + textarea.style.opacity = '0'; + textarea.style.pointerEvents = 'none'; + document.body.appendChild(textarea); + textarea.focus(); + textarea.select(); + document.execCommand('copy'); + textarea.remove(); + }; document.addEventListener('contextmenu', (e) => { const li = e.target.closest('.manage-list-item'); - if (li) { + const rowCol = e.target.closest('.row-col'); + if (li && rowCol) { const cb = li.querySelector('input[type="checkbox"]'); if (cb && cb.dataset.path && cb.dataset.path !== "path_unknown") { e.preventDefault(); ctxTarget = cb.dataset.path; - const span = contextMenu.querySelector('span'); - span.textContent = getMsg('ctx_open_loc'); + ctxCellText = rowCol.textContent; + contextMenu.querySelector('#ctx_open_location span').textContent = getMsg('ctx_open_loc'); + contextMenu.querySelector('#ctx_copy_cell span').textContent = getMsg('ctx_copy_cell'); contextMenu.style.left = `${e.clientX}px`; contextMenu.style.top = `${e.clientY}px`; contextMenu.classList.add('show'); @@ -1120,6 +1145,11 @@ document.addEventListener('DOMContentLoaded', () => { if (window.pywebview && ctxTarget) window.pywebview.api.open_file_location(ctxTarget); contextMenu.classList.remove('show'); }); + document.getElementById('ctx_copy_cell').addEventListener('click', async () => { + const text = ctxCellText; + contextMenu.classList.remove('show'); + if (text !== null) await copyTextToClipboard(text); + }); initI18nKeys();