diff --git a/src/common/CSyntaxHighlighter.cpp b/src/common/CSyntaxHighlighter.cpp index 92df07b3..8db3bcf5 100644 --- a/src/common/CSyntaxHighlighter.cpp +++ b/src/common/CSyntaxHighlighter.cpp @@ -24,6 +24,16 @@ void CSyntaxHighlighter::setEnableHighlight(bool isEnable) m_bHighlight = isEnable; } +void CSyntaxHighlighter::setInvalidCharHighlight(bool enable) +{ + qDebug() << "CSyntaxHighlighter::setInvalidCharHighlight()" << enable; + m_bInvalidCharHighlight = enable; + if (enable) { + setEnableHighlight(true); + } + rehighlight(); +} + void CSyntaxHighlighter::highlightBlock(const QString &text) { if (!m_bHighlight) { @@ -33,4 +43,18 @@ void CSyntaxHighlighter::highlightBlock(const QString &text) qDebug() << "CSyntaxHighlighter::highlightBlock()"; KSyntaxHighlighting::SyntaxHighlighter::highlightBlock(text); + + // 叠加 \00 无效字符高亮:红色背景 + 白色文字 + if (m_bInvalidCharHighlight) { + QTextCharFormat fmt; + fmt.setBackground(QColor("#FF0000")); + fmt.setForeground(QColor("#FFFFFF")); + // 匹配字面量 \00(反斜杠 + 两个零) + static const QRegularExpression re("\\\\00"); + QRegularExpressionMatchIterator it = re.globalMatch(text); + while (it.hasNext()) { + QRegularExpressionMatch match = it.next(); + setFormat(match.capturedStart(), match.capturedLength(), fmt); + } + } } diff --git a/src/common/CSyntaxHighlighter.h b/src/common/CSyntaxHighlighter.h index 4ff05468..f58892a4 100644 --- a/src/common/CSyntaxHighlighter.h +++ b/src/common/CSyntaxHighlighter.h @@ -6,6 +6,9 @@ #include #include #include +#include +#include +#include using namespace KSyntaxHighlighting; class CSyntaxHighlighter : public SyntaxHighlighter @@ -15,10 +18,12 @@ class CSyntaxHighlighter : public SyntaxHighlighter explicit CSyntaxHighlighter(QObject *parent = nullptr); explicit CSyntaxHighlighter(QTextDocument *pDocument); void setEnableHighlight(bool isEnable); + void setInvalidCharHighlight(bool enable); protected: virtual void highlightBlock(const QString & text) override; private: bool m_bHighlight = false; + bool m_bInvalidCharHighlight = false; }; diff --git a/src/common/fileloadthread.cpp b/src/common/fileloadthread.cpp index adacace0..97a2437c 100644 --- a/src/common/fileloadthread.cpp +++ b/src/common/fileloadthread.cpp @@ -50,10 +50,19 @@ void FileLoadThread::run() // 发送文件头信息,用于预先加载数据 QString textEncode = QString::fromLocal8Bit(encode); if (textEncode.contains("ASCII", Qt::CaseInsensitive) || textEncode.contains("UTF-8", Qt::CaseInsensitive)) { - emit sigPreProcess(encode, indata); + if (indata.contains('\x00')) { + QByteArray headData = indata; + headData.replace('\x00', "\\00"); + emit sigPreProcess(encode, headData); + } else { + emit sigPreProcess(encode, indata); + } } else { QByteArray outHeadData; DetectCode::ChangeFileEncodingFormat(indata, outHeadData, textEncode, QString("UTF-8")); + if (outHeadData.contains('\x00')) { + outHeadData.replace('\x00', "\\00"); + } emit sigPreProcess(encode, outHeadData); } } @@ -75,10 +84,17 @@ void FileLoadThread::run() qWarning() << "FileLoadThread read error:" << e.what() << "at" << m_strFilePath; file.close(); - emit sigLoadFinished(encode, indata, true); + emit sigLoadFinished(encode, indata, true, false); return; } + // NUL 字节检测与转义:将每个 \x00 替换为三个 ASCII 字符 \00 + bool hasNul = indata.contains('\x00'); + if (hasNul) { + qDebug() << "NUL bytes detected in file, escaping to \\00"; + indata.replace('\x00', "\\00"); + } + if (!m_encodeHint.isEmpty()) { qDebug() << "Using encoding hint:" << m_encodeHint; encode = m_encodeHint; @@ -98,17 +114,17 @@ void FileLoadThread::run() qDebug() << "Final encoding detected:" << textEncode; if (textEncode.contains("ASCII", Qt::CaseInsensitive) || textEncode.contains("UTF-8", Qt::CaseInsensitive)) { qDebug() << "Using original encoding, no conversion needed"; - emit sigLoadFinished(encode, indata, false); + emit sigLoadFinished(encode, indata, false, hasNul); } else { qDebug() << "Converting from" << textEncode << "to UTF-8"; QByteArray outData; DetectCode::ChangeFileEncodingFormat(indata, outData, textEncode, QString("UTF-8")); - emit sigLoadFinished(encode, outData, false); + emit sigLoadFinished(encode, outData, false, hasNul); qDebug() << "Encoding conversion completed, output size:" << outData.size(); } } else { qWarning() << "Failed to open file:" << m_strFilePath << "error:" << file.errorString(); - emit sigLoadFinished("", "", true); + emit sigLoadFinished("", "", true, false); } qDebug() << "FileLoadThread finished processing:" << m_strFilePath; diff --git a/src/common/fileloadthread.h b/src/common/fileloadthread.h index 4d9737bf..a0808c77 100644 --- a/src/common/fileloadthread.h +++ b/src/common/fileloadthread.h @@ -20,7 +20,7 @@ class FileLoadThread : public QThread signals: // 预处理信号,优先处理文件头,防止出现加载时间过长的情况 void sigPreProcess(const QByteArray &encode, const QByteArray &content); - void sigLoadFinished(const QByteArray &encode, const QByteArray &content, bool error = false); + void sigLoadFinished(const QByteArray &encode, const QByteArray &content, bool error = false, bool hasNul = false); private: QString m_strFilePath; diff --git a/src/controls/warningnotices.cpp b/src/controls/warningnotices.cpp index 9cfe8afe..c7798c1f 100644 --- a/src/controls/warningnotices.cpp +++ b/src/controls/warningnotices.cpp @@ -24,12 +24,16 @@ WarningNotices::WarningNotices(MessageType notifyType, QWidget *parent) setIcon(QIcon(":/images/warning.svg")); m_reloadBtn = new QPushButton(tr("Reload"), this); m_saveAsBtn = new QPushButton(qApp->translate("Window", "Save as"), this); + m_editAnywayBtn = new QPushButton(tr("Edit Anyway"), this); m_reloadBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); m_saveAsBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_editAnywayBtn->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_editAnywayBtn->setVisible(false); qDebug() << "Warning buttons initialized"; connect(m_reloadBtn, &QPushButton::clicked, this, &WarningNotices::slotreloadBtnClicked); connect(m_saveAsBtn, &QPushButton::clicked, this, &WarningNotices::slotsaveAsBtnClicked); + connect(m_editAnywayBtn, &QPushButton::clicked, this, &WarningNotices::slotEditAnywayBtnClicked); qDebug() << "Warning button signals connected"; #ifdef DTKWIDGET_CLASS_DSizeMode @@ -112,3 +116,21 @@ void WarningNotices::slotsaveAsBtnClicked() emit saveAsBtnClicked(); qDebug() << "slotsaveAsBtnClicked end"; } + +void WarningNotices::setEditAnywayBtn() +{ + qDebug() << "setEditAnywayBtn"; + m_reloadBtn->setVisible(false); + m_saveAsBtn->setVisible(false); + m_editAnywayBtn->setVisible(true); + setWidget(m_editAnywayBtn); + qDebug() << "setEditAnywayBtn end"; +} + +void WarningNotices::slotEditAnywayBtnClicked() +{ + qDebug() << "slotEditAnywayBtnClicked"; + this->hide(); + emit editAnywayBtnClicked(); + qDebug() << "slotEditAnywayBtnClicked end"; +} diff --git a/src/controls/warningnotices.h b/src/controls/warningnotices.h index 3ef6db0f..baae9d8a 100644 --- a/src/controls/warningnotices.h +++ b/src/controls/warningnotices.h @@ -23,19 +23,23 @@ class WarningNotices : public DFloatingMessage void setReloadBtn(); void setSaveAsBtn(); void clearBtn(); + void setEditAnywayBtn(); signals: void reloadBtnClicked(); void saveAsBtnClicked(); void closeBtnClicked(); + void editAnywayBtnClicked(); public slots: void slotreloadBtnClicked(); void slotsaveAsBtnClicked(); + void slotEditAnywayBtnClicked(); private: QPushButton *m_reloadBtn; QPushButton *m_saveAsBtn; + QPushButton *m_editAnywayBtn; QHBoxLayout *m_pLayout; }; diff --git a/src/editor/editwrapper.cpp b/src/editor/editwrapper.cpp index 6e9d84c1..a6fa09c4 100644 --- a/src/editor/editwrapper.cpp +++ b/src/editor/editwrapper.cpp @@ -119,6 +119,7 @@ EditWrapper::EditWrapper(Window *window, QWidget *parent) connect(m_pTextEdit, &TextEdit::cursorModeChanged, this, &EditWrapper::handleCursorModeChanged); connect(m_pWaringNotices, &WarningNotices::reloadBtnClicked, this, &EditWrapper::reloadModifyFile); connect(m_pWaringNotices, &WarningNotices::saveAsBtnClicked, m_pWindow, &Window::saveAsFile); + connect(m_pWaringNotices, &WarningNotices::editAnywayBtnClicked, this, &EditWrapper::onEditAnyway); // NOTE: 文本高亮会触发重新布局,与界面布局(拖拽、放大窗口)变更时的布局操作冲突,因此调整更新顺序,在布局后刷新高亮 connect(m_pTextEdit->verticalScrollBar(), &QScrollBar::valueChanged, this, [this](int) { qDebug() << "EditWrapper connect verticalScrollBar valueChanged"; @@ -604,6 +605,13 @@ QString EditWrapper::getTextEncode() bool EditWrapper::saveFile(QByteArray encode) { qDebug() << "EditWrapper saveFile, encode:" << encode; + + // 预览模式下不允许直接静默保存,交由 Window 层确认弹窗 + if (m_bInvalidCharPreview) { + qDebug() << "EditWrapper saveFile, in preview mode, returning false"; + return false; + } + QString qstrFilePath = m_pTextEdit->getTruePath(); hideWarningNotices(); @@ -643,6 +651,54 @@ bool EditWrapper::saveFile(QByteArray encode) return ok; } +void EditWrapper::onEditAnyway() +{ + qDebug() << "EditWrapper onEditAnyway, allowing edit in preview mode"; + m_bInvalidCharEditAllowed = true; + m_pTextEdit->setReadOnly(false); + m_pWaringNotices->hide(); + // 保持 m_bInvalidCharPreview = true,直到 Save As 或 Save Anyway 成功 +} + +void EditWrapper::exitInvalidCharPreview() +{ + qDebug() << "EditWrapper exitInvalidCharPreview, exiting preview mode"; + m_bInvalidCharPreview = false; + m_bInvalidCharEditAllowed = false; + m_sInvalidCharOriginalPath.clear(); + m_pTextEdit->setReadOnly(false); + m_pWaringNotices->hide(); + if (m_pSyntaxHighlighter) { + m_pSyntaxHighlighter->setInvalidCharHighlight(false); + } + updateModifyStatus(false); +} + +bool EditWrapper::forceSaveInvalidCharFile() +{ + qDebug() << "EditWrapper forceSaveInvalidCharFile, saving to original path:" << m_sInvalidCharOriginalPath; + QString savePath = m_sInvalidCharOriginalPath; + TextFileSaver saver(m_pTextEdit->document()); + saver.setFilePath(savePath); + saver.setEncoding(m_sCurEncode.toUtf8()); + saver.setEndlineFormat(m_pBottomBar->getEndlineFormat() == BottomBar::EndlineFormat::Windows); + + bool ok = saver.save(); + if (ok) { + qDebug() << "EditWrapper forceSaveInvalidCharFile, save succeeded"; + m_sFirstEncode = m_sCurEncode; + QFileInfo fi(savePath); + m_tModifiedDateTime = fi.lastModified(); + m_bIsTemFile = false; + m_pTextEdit->setTextEncode(m_sCurEncode); + m_pTextEdit->writeEncodeHistoryRecord(); + exitInvalidCharPreview(); + } else { + qDebug() << "EditWrapper forceSaveInvalidCharFile, save failed"; + } + return ok; +} + void EditWrapper::getPlainTextContent(QByteArray &plainTextContent) { qDebug() << "EditWrapper getPlainTextContent"; @@ -975,7 +1031,7 @@ void EditWrapper::handleFilePreProcess(const QByteArray &encode, const QByteArra * @param encode 文件编码 * @param content 完整文件内容 */ -void EditWrapper::handleFileLoadFinished(const QByteArray &encode, const QByteArray &content, bool error) +void EditWrapper::handleFileLoadFinished(const QByteArray &encode, const QByteArray &content, bool error, bool hasNul) { qDebug() << "File load finished. Encoding:" << encode << "Error:" << error << "Preprocessed:" << m_bHasPreProcess; @@ -1017,6 +1073,32 @@ void EditWrapper::handleFileLoadFinished(const QByteArray &encode, const QByteAr m_pTextEdit->setReadOnly(true); } + // 无效字符(NUL)预览模式初始化 + if (hasNul) { + qDebug() << "EditWrapper handleFileLoadFinished, hasNul is true, entering preview mode"; + m_bInvalidCharPreview = true; + m_bInvalidCharEditAllowed = false; + m_sInvalidCharOriginalPath = m_pTextEdit->getTruePath(); + m_pTextEdit->setReadOnly(true); + m_pWaringNotices->setMessage(tr("The file contains invalid characters (NUL). Preview mode is read-only.")); + m_pWaringNotices->setEditAnywayBtn(); + m_pWaringNotices->show(); + DMessageManager::instance()->sendMessage(m_pTextEdit, m_pWaringNotices); + // 确保 CSyntaxHighlighter 存在(无语法定义的文件如 .txt 不会在 reinitOnFileLoad 中创建) + if (!m_pSyntaxHighlighter) { + m_pSyntaxHighlighter = new CSyntaxHighlighter(m_pTextEdit->document()); + QString themePath = Settings::instance()->settings->option("advance.editor.theme")->value().toString(); + if (themePath.contains("dark")) { + m_pSyntaxHighlighter->setTheme(m_Repository.defaultTheme(KSyntaxHighlighting::Repository::DarkTheme)); + } else { + m_pSyntaxHighlighter->setTheme(m_Repository.defaultTheme(KSyntaxHighlighting::Repository::LightTheme)); + } + } + if (m_pSyntaxHighlighter) { + m_pSyntaxHighlighter->setInvalidCharHighlight(true); + } + } + if (m_bQuit) { qDebug() << "EditWrapper handleFileLoadFinished, m_bQuit is true, return"; return; diff --git a/src/editor/editwrapper.h b/src/editor/editwrapper.h index 466eb2ee..1678b1c0 100644 --- a/src/editor/editwrapper.h +++ b/src/editor/editwrapper.h @@ -119,6 +119,16 @@ class EditWrapper : public QWidget inline CSyntaxHighlighter *getSyntaxHighlighter() const { return m_pSyntaxHighlighter; } + // 无效字符预览模式访问器 + inline bool isInvalidCharPreview() const + { return m_bInvalidCharPreview; } + inline bool isInvalidCharEditAllowed() const + { return m_bInvalidCharEditAllowed; } + inline QString invalidCharOriginalPath() const + { return m_sInvalidCharOriginalPath; } + void exitInvalidCharPreview(); + bool forceSaveInvalidCharFile(); + signals: void sigClearDoubleCharaterEncode(); @@ -139,7 +149,7 @@ class EditWrapper : public QWidget public slots: // 处理文档预加载数据 void handleFilePreProcess(const QByteArray &encode, const QByteArray &content); - void handleFileLoadFinished(const QByteArray &encode, const QByteArray &content, bool error); + void handleFileLoadFinished(const QByteArray &encode, const QByteArray &content, bool error, bool hasNul = false); void OnThemeChangeSlot(QString theme); void UpdateBottomBarWordCnt(int cnt); void OnUpdateHighlighter(); @@ -147,6 +157,7 @@ public slots: void setTemFile(bool value); // 设置恢复光标位置(用于懒加载恢复,避免 O(N²) 扫描) void setRestoreCursorPosition(int position); + void onEditAnyway(); private: //第一次打开文件编码 @@ -183,6 +194,11 @@ public slots: bool m_bAsyncReadFileFinished = false; bool m_bHasPreProcess = false; // 预处理标识 int m_nRestoreCursorPosition = -1; // 恢复光标位置提示(-1 表示不指定) + + // 无效字符(NUL)预览模式状态 + bool m_bInvalidCharPreview = false; + bool m_bInvalidCharEditAllowed = false; + QString m_sInvalidCharOriginalPath; }; #endif diff --git a/src/widgets/window.cpp b/src/widgets/window.cpp index ffd8c408..3367086c 100644 --- a/src/widgets/window.cpp +++ b/src/widgets/window.cpp @@ -968,11 +968,51 @@ bool Window::closeTab(const QString &filePath) // need to prompt whether to save. else { QFileInfo fileInfo(filePath); - isModified = false; - if (m_tabbar->textAt(m_tabbar->currentIndex()).front() == "*") { - qDebug() << "Tab name starts with '*', indicating modified state"; - isModified = true; + + // 无效字符预览模式拦截:复用与 Ctrl+S 相同的三按钮确认弹窗 + if (wrapper->isInvalidCharPreview()) { + if (wrapper->isInvalidCharEditAllowed() && isModified) { + QString fileName = QFileInfo(filePath).fileName(); + int res = confirmInvalidCharSave(fileName); + switch (res) { + case 0: // Don't Save + qDebug() << "Preview closeTab: Don't Save, closing tab"; + removeWrapper(filePath, true); + m_tabbar->closeCurrentTab(filePath); + return true; + case 1: // Save As + { + qDebug() << "Preview closeTab: Save As"; + QString newPath = saveAsFileToDisk(); + if (!newPath.isEmpty()) { + // saveAsFileToDisk 成功后 wrapper 映射键已更新为 newPath,必须用 newPath 关闭 + removeWrapper(newPath, true); + m_tabbar->closeCurrentTab(newPath); + return true; + } + return false; // 失败或取消不关闭 + } + case 2: // Save Anyway + qDebug() << "Preview closeTab: Save Anyway"; + if (wrapper->forceSaveInvalidCharFile()) { + removeWrapper(filePath, true); + m_tabbar->closeCurrentTab(filePath); + return true; + } + return false; + default: // 取消 + qDebug() << "Preview closeTab: cancelled"; + return false; + } + } else { + // 预览模式但未编辑(未点 Edit Anyway 或无修改),直接关闭不提示 + qDebug() << "Preview closeTab: no edits, closing tab without prompt"; + removeWrapper(filePath, true); + m_tabbar->closeCurrentTab(filePath); + return true; + } } + if (isModified) { qDebug() << "File is modified, prompting to save"; DDialog *dialog = createDialog(tr("Do you want to save this file?"), ""); @@ -1298,6 +1338,24 @@ void Window::openFile() qDebug() << "Exit openFile"; } +int Window::confirmInvalidCharSave(const QString &fileName) +{ + qDebug() << "confirmInvalidCharSave for file:" << fileName; + DDialog *dialog = new DDialog( + tr("Invalid characters detected while saving \"%1\"").arg(fileName), + tr("If you force save this file, it may cause file corruption. Still want to save?"), + this); + dialog->setIcon(QIcon::fromTheme("dialog-warning")); + dialog->addButton(tr("Don't Save"), false, DDialog::ButtonNormal); + dialog->addButton(tr("Save As"), true, DDialog::ButtonRecommend); + dialog->addButton(tr("Save Anyway"), false, DDialog::ButtonWarning); + dialog->setCloseButtonVisible(false); + int res = dialog->exec(); + dialog->deleteLater(); + // 0=Don't Save, 1=Save As, 2=Save Anyway, -1=取消 + return res; +} + bool Window::saveFile() { qDebug() << "Saving current file"; @@ -1310,6 +1368,36 @@ bool Window::saveFile() return false; } + // 无效字符预览模式拦截:弹出三按钮确认框 + if (wrapperEdit->isInvalidCharPreview()) { + // 未编辑(未点 Edit Anyway)时无需保存,直接返回 + if (!wrapperEdit->isInvalidCharEditAllowed()) { + qDebug() << "Preview save: no edits made, nothing to save"; + return false; + } + QString filePath = wrapperEdit->textEditor()->getTruePath(); + QString fileName = QFileInfo(filePath).fileName(); + int res = confirmInvalidCharSave(fileName); + switch (res) { + case 0: // Don't Save + qDebug() << "Preview save: Don't Save"; + return false; + case 1: // Save As + qDebug() << "Preview save: Save As"; + return saveAsFile(); + case 2: // Save Anyway + qDebug() << "Preview save: Save Anyway"; + if (wrapperEdit->forceSaveInvalidCharFile()) { + showNotify(tr("Saved successfully")); + return true; + } + return false; + default: // 取消 + qDebug() << "Preview save: cancelled"; + return false; + } + } + bool isDraftFile = wrapperEdit->isDraftFile(); //bool isEmpty = wrapperEdit->isPlainTextEmpty(); QString filePath = wrapperEdit->textEditor()->getTruePath(); @@ -1433,6 +1521,19 @@ QString Window::saveAsFileToDisk() Settings::instance()->setSavePath(PathSettingWgt::LastOptBox, QFileInfo(newFilePath).absolutePath()); Settings::instance()->setSavePath(PathSettingWgt::CurFileBox, QFileInfo(newFilePath).absolutePath()); + // 预览模式下拒绝另存为原文件路径 + if (wrapper->isInvalidCharPreview()) { + QString originalPath = wrapper->invalidCharOriginalPath(); + if (QFileInfo(originalPath).absoluteFilePath() == QFileInfo(newFilePath).absoluteFilePath()) { + qDebug() << "Save As rejected: same as original path in preview mode"; + DMessageManager::instance()->sendMessage( + m_editorWidget->currentWidget(), + QIcon(":/images/warning.svg"), + tr("Cannot save as the original file in preview mode. Please choose a different path.")); + return QString(); + } + } + // 保存原始文件路径,用于后续更新 QString oldFilePath = wrapper->filePath(); @@ -1460,6 +1561,11 @@ QString Window::saveAsFileToDisk() // 保存成功后再更新路径,防止文件还未保存完成就触发文件是否存在的检测 wrapper->updatePath(oldFilePath, newFilePath); + // 预览模式 Save As 成功后退出预览模式 + if (wrapper->isInvalidCharPreview()) { + wrapper->exitInvalidCharPreview(); + } + // 更新文件编码 wrapper->bottomBar()->setEncodeName(encode); @@ -2911,7 +3017,12 @@ void Window::backupFile() QJsonDocument document; jsonObject.insert("localPath", localPath); jsonObject.insert("cursorPosition", QString::number(wrapper->textEditor()->textCursor().position())); - jsonObject.insert("modify", wrapper->isModified()); + // 预览模式下不持久化修改状态 + if (wrapper->isInvalidCharPreview()) { + jsonObject.insert("modify", false); + } else { + jsonObject.insert("modify", wrapper->isModified()); + } jsonObject.insert("lastModifiedTime", wrapper->getLastModifiedTime().toString()); QList bookmarkList = wrapper->textEditor()->getBookmarkInfo(); if (!bookmarkList.isEmpty()) { @@ -2937,7 +3048,10 @@ void Window::backupFile() } //保存备份文件 - if (Utils::isDraftFile(filePath)) { + if (wrapper->isInvalidCharPreview()) { + // 预览模式跳过备份,不写 temFilePath,不保存临时文件 + qInfo() << "preview mode, skip backup file"; + } else if (Utils::isDraftFile(filePath)) { qInfo() << "is draft file, save to draft dir"; wrapper->saveTemFile(filePath); } else { diff --git a/src/widgets/window.h b/src/widgets/window.h index a0f9471d..fc092eed 100644 --- a/src/widgets/window.h +++ b/src/widgets/window.h @@ -211,6 +211,7 @@ public Q_SLOTS: int getBlankFileIndex(); DDialog *createDialog(const QString &title, const QString &content); + int confirmInvalidCharSave(const QString &fileName); void slotLoadContentTheme(DGuiApplicationHelper::ColorType themeType); void slotSettingResetTheme(const QString &path); diff --git a/translations/deepin-editor.ts b/translations/deepin-editor.ts index 9be47cd0..2d207f67 100644 --- a/translations/deepin-editor.ts +++ b/translations/deepin-editor.ts @@ -102,6 +102,11 @@ The file cannot be read, which may be too large or has been damaged! The file cannot be read, which may be too large or has been damaged! + + + The file contains invalid characters (NUL). Preview mode is read-only. + The file contains invalid characters (NUL). Preview mode is read-only. + FindBar @@ -1237,6 +1242,11 @@ Reload Reload + + + Edit Anyway + Edit Anyway + Window @@ -1368,5 +1378,35 @@ Discard Discard + + + Invalid characters detected while saving "%1" + Invalid characters detected while saving "%1" + + + + If you force save this file, it may cause file corruption. Still want to save? + If you force save this file, it may cause file corruption. Still want to save? + + + + Don't Save + Don't Save + + + + Save As + Save As + + + + Save Anyway + Save Anyway + + + + Cannot save as the original file in preview mode. Please choose a different path. + Cannot save as the original file in preview mode. Please choose a different path. + diff --git a/translations/deepin-editor_zh_CN.ts b/translations/deepin-editor_zh_CN.ts index 594c375f..4ac5c01e 100644 --- a/translations/deepin-editor_zh_CN.ts +++ b/translations/deepin-editor_zh_CN.ts @@ -100,6 +100,11 @@ The file cannot be read, which may be too large or has been damaged! 无法读取该文件,文件可能过大或损坏 + + + The file contains invalid characters (NUL). Preview mode is read-only. + 文件包含无效字符(NUL)。预览模式为只读。 + FindBar @@ -1235,6 +1240,11 @@ Reload 重新载入 + + + Edit Anyway + 仍然编辑 + Window @@ -1366,5 +1376,35 @@ Discard 不保存 + + + Invalid characters detected while saving "%1" + 保存"%1"时检测到无效字符 + + + + If you force save this file, it may cause file corruption. Still want to save? + 强制保存此文件可能导致文件损坏。仍然要保存吗? + + + + Don't Save + 不保存 + + + + Save As + 另存为 + + + + Save Anyway + 强制保存 + + + + Cannot save as the original file in preview mode. Please choose a different path. + 预览模式下不能另存为原文件。请选择其他路径。 + diff --git a/translations/deepin-editor_zh_HK.ts b/translations/deepin-editor_zh_HK.ts index 128133ac..6b6b7c94 100644 --- a/translations/deepin-editor_zh_HK.ts +++ b/translations/deepin-editor_zh_HK.ts @@ -100,6 +100,11 @@ The file cannot be read, which may be too large or has been damaged! 無法讀取該文件,文件可能過大或損壞 + + + The file contains invalid characters (NUL). Preview mode is read-only. + 文件包含無效字元(NUL)。預覽模式為唯讀。 + FindBar @@ -1235,6 +1240,11 @@ Reload 重新載入 + + + Edit Anyway + 仍然編輯 + Window @@ -1366,5 +1376,35 @@ Discard 不保存 + + + Invalid characters detected while saving "%1" + 保存「%1」時偵測到無效字元 + + + + If you force save this file, it may cause file corruption. Still want to save? + 強制保存此文件可能導致文件損壞。仍然要保存嗎? + + + + Don't Save + 不保存 + + + + Save As + 另存為 + + + + Save Anyway + 強制保存 + + + + Cannot save as the original file in preview mode. Please choose a different path. + 預覽模式下不能另存為原文件。請選擇其他路徑。 + - \ No newline at end of file + diff --git a/translations/deepin-editor_zh_TW.ts b/translations/deepin-editor_zh_TW.ts index 4a4cd4bc..a683f470 100644 --- a/translations/deepin-editor_zh_TW.ts +++ b/translations/deepin-editor_zh_TW.ts @@ -100,6 +100,11 @@ The file cannot be read, which may be too large or has been damaged! 無法讀取該文件,文件可能過大或損壞 + + + The file contains invalid characters (NUL). Preview mode is read-only. + 文件包含無效字元(NUL)。預覽模式為唯讀。 + FindBar @@ -1235,6 +1240,11 @@ Reload 重新載入 + + + Edit Anyway + 仍然編輯 + Window @@ -1366,5 +1376,35 @@ Discard 不儲存 + + + Invalid characters detected while saving "%1" + 儲存「%1」時偵測到無效字元 + + + + If you force save this file, it may cause file corruption. Still want to save? + 強制儲存此文件可能導致文件損壞。仍然要儲存嗎? + + + + Don't Save + 不儲存 + + + + Save As + 另存為 + + + + Save Anyway + 強制儲存 + + + + Cannot save as the original file in preview mode. Please choose a different path. + 預覽模式下不能另存為原文件。請選擇其他路徑。 + - \ No newline at end of file +