- 引入 log4net 库,统一日志记录方式,提升可维护性。 - 优化异常处理,增加详细日志记录,增强代码健壮性。 - 调整资源文件引用,新增图标资源,删除无用资源。 - 优化文档事件处理逻辑,改进面板显示与隐藏逻辑。 - 增加对 WPS 环境的支持,动态调整功能行为。 - 禁用部分功能(如常识性检测、客服、升级和帮助)。 - 删除冗余代码,清理注释,统一代码风格。 - 更新程序集版本至 2.2.5,改进调试与生产环境配置。
1027 lines
36 KiB
C#
1027 lines
36 KiB
C#
using AIProofread.Controls;
|
||
using AIProofread.core;
|
||
using AIProofread.Model;
|
||
using AIProofread.Util;
|
||
using log4net;
|
||
using Microsoft.Office.Interop.Word;
|
||
using Microsoft.Web.WebView2.Core;
|
||
using Microsoft.Web.WebView2.WinForms;
|
||
using Newtonsoft.Json;
|
||
using NPOI;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Diagnostics;
|
||
using System.IO;
|
||
using System.Runtime.InteropServices;
|
||
using System.Text.RegularExpressions;
|
||
using System.Windows.Forms;
|
||
using UtilLib;
|
||
using Document = Microsoft.Office.Interop.Word.Document;
|
||
using Task = System.Threading.Tasks.Task;
|
||
|
||
namespace AIProofread
|
||
{
|
||
public enum BridgeEvent
|
||
{
|
||
LoginSuccess,
|
||
WindowClose
|
||
}
|
||
public delegate void BridgeEventHandler(object sender, EventArgs e);
|
||
|
||
|
||
[ClassInterface(ClassInterfaceType.AutoDual)]
|
||
[ComVisible(true)]
|
||
public class Bridge
|
||
{
|
||
public static Bridge bridge = new Bridge();
|
||
|
||
private static readonly Dictionary<string, WebView2> webViewDict = new Dictionary<string, WebView2>();
|
||
|
||
private static readonly Dictionary<BridgeEvent, List<BridgeEventHandler>> eventHandlers = new Dictionary<BridgeEvent, List<BridgeEventHandler>>();
|
||
|
||
public static Dictionary<int, ProofreadItem> marks;
|
||
|
||
//private static int selectProofreadId = -1;
|
||
|
||
private static object missing = System.Reflection.Missing.Value;
|
||
|
||
private static UpgradeData CurrentUpgrade = null;
|
||
public static readonly ILog Logger = LogHelper.GetLogger(typeof(Bridge));
|
||
|
||
public void ShowUpgradeView()
|
||
{
|
||
// 统一使用更新程序
|
||
StartUpgradeProcess();
|
||
//if (CurrentUpgrade == null)
|
||
//{
|
||
// CheckPluginUpgrade();
|
||
// if (CurrentUpgrade == null)
|
||
// {
|
||
// showDialog("获取版本信息失败,请稍后再试");
|
||
// return;
|
||
// }
|
||
//}
|
||
//var needUpgrade = CurrentUpgrade.NeedUpgrade(Config.APP_VERSION);
|
||
//if (!needUpgrade)
|
||
//{
|
||
// showDialog("当前版本为最新版本,无需升级");
|
||
// return;
|
||
//}
|
||
//if (CurrentUpgrade.Ext == 1)
|
||
//{
|
||
// var ret = MessageBox.Show(CurrentUpgrade.Message, "是否确认更新", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question);
|
||
// if (ret == DialogResult.Yes)
|
||
// {
|
||
// OpenUrlWithOsBrowser(CurrentUpgrade.DownloadUrl);
|
||
// }
|
||
//}
|
||
//else
|
||
//{
|
||
//}
|
||
}
|
||
|
||
public bool ShouldUpgradeForced()
|
||
{
|
||
return CurrentUpgrade != null && CurrentUpgrade.NeedUpgrade(Config.APP_VERSION) && CurrentUpgrade.UpgradeType == 1;
|
||
}
|
||
|
||
public void SendNoticeToCheckAll()
|
||
{
|
||
Globals.ThisAddIn.ShowDetection();
|
||
Globals.ThisAddIn.formCommonsenseDetection.SendMessageToWeb("detect-all", null);
|
||
}
|
||
public void SendNoticeToCheckRange(int start, int end)
|
||
{
|
||
Globals.ThisAddIn.ShowDetection();
|
||
// 获取当前选中的选区的首尾段落起始与结束位置
|
||
if (start == -1 || end == -1)
|
||
{
|
||
var currectSelectRange = Globals.ThisAddIn.ribbon.currectSelectRange;
|
||
start = currectSelectRange.Start;
|
||
end = currectSelectRange.End;
|
||
}
|
||
var data = JSONObject.Create().Put("start", start).Put("end", end).ToString();
|
||
Globals.ThisAddIn.formCommonsenseDetection.SendMessageToWeb("detect-range", data);
|
||
}
|
||
public void SendNoticeToShowCheckHistory()
|
||
{
|
||
Globals.ThisAddIn.ShowDetection();
|
||
Globals.ThisAddIn.formCommonsenseDetection.SendMessageToWeb("show-history", null);
|
||
}
|
||
|
||
public void HasNewVersion()
|
||
{
|
||
Globals.ThisAddIn.ribbon.ShowNewVersionIcon();
|
||
}
|
||
/// <summary>
|
||
/// 检查插件更新信息
|
||
/// </summary>
|
||
public void CheckPluginUpgrade()
|
||
{
|
||
try
|
||
{
|
||
string source = HttpUtil.GetHttpSource(Config.WEB_PATH + "api/v1/common/download/version");
|
||
if (source == null) return;
|
||
|
||
UpgradeSource data = JsonConvert.DeserializeObject<UpgradeSource>(source);
|
||
if (data == null || data.Code != 0) return;
|
||
CurrentUpgrade = data.Data;
|
||
|
||
// 是否需要强制升级
|
||
if (ShouldUpgradeForced())
|
||
{
|
||
var result = MessageBox.Show("插件有新的版本,是否立即更新?", "AI校对王提示", MessageBoxButtons.YesNo);
|
||
if (result == DialogResult.Yes)
|
||
{
|
||
// 显示升级框
|
||
ShowUpgradeView();
|
||
}
|
||
else
|
||
{
|
||
Globals.ThisAddIn.ribbon.SetBtnStatus("disable-by-upgrade", false);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error(ex);
|
||
}
|
||
}
|
||
|
||
public string GetAppVersion()
|
||
{
|
||
|
||
Dictionary<string, object> data = new Dictionary<string, object>();
|
||
data["version"] = Config.APP_VERSION;
|
||
data["platform"] = Config.IS_WPS ? "wps" : "word";
|
||
data["environment"] = Config.APP_ENV.ToString();
|
||
data["deviceId"] = Config.DeviceId;
|
||
return JsonConvert.SerializeObject(data);
|
||
}
|
||
public void SetBtnStatus(string key, bool status)
|
||
{
|
||
Globals.ThisAddIn.ribbon.SetBtnStatus(key, status);
|
||
}
|
||
|
||
public void ShowDialog(string message, string confirmText = "", string confirmAction = "")
|
||
{
|
||
Globals.ThisAddIn.ActiveDocument?.ShowDialog(message, confirmText, confirmAction);
|
||
}
|
||
|
||
public int getMinWIdth()
|
||
{
|
||
return Globals.ThisAddIn.GetMinWidth();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加事件
|
||
/// </summary>
|
||
/// <param name="eventName"></param>
|
||
/// <param name="handler"></param>
|
||
public static void AddEventHandler(BridgeEvent eventName, BridgeEventHandler handler)
|
||
{
|
||
if (!eventHandlers.ContainsKey(eventName))
|
||
{
|
||
eventHandlers.Add(eventName, new List<BridgeEventHandler>());
|
||
}
|
||
eventHandlers[eventName].Add(handler);
|
||
}
|
||
public static void RemoveEventHandler(BridgeEvent eventName, BridgeEventHandler handler)
|
||
{
|
||
if (eventHandlers.ContainsKey(eventName))
|
||
{
|
||
eventHandlers[eventName].Remove(handler);
|
||
}
|
||
}
|
||
|
||
public void SetCurrentDocumentId(int id)
|
||
{
|
||
SetDocumentId(id, Globals.ThisAddIn.Application.ActiveDocument);
|
||
}
|
||
|
||
|
||
public void SetDocumentId(int id, Document document)
|
||
{
|
||
Globals.ThisAddIn.SetDocumentId(document, id);
|
||
}
|
||
public DocumentInfo GetDocumentById(int id)
|
||
{
|
||
return Globals.ThisAddIn.GetDocumentById(id);
|
||
}
|
||
|
||
public int GetCurrentDocumentId()
|
||
{
|
||
return Globals.ThisAddIn.ActiveDocument.Id;
|
||
}
|
||
|
||
public int GeIdBytDocument(Document document)
|
||
{
|
||
var doc = Globals.ThisAddIn.documentList.Get(document);
|
||
if (doc != null)
|
||
{
|
||
return doc.Id;
|
||
}
|
||
return doc != null ? doc.Id : 0;
|
||
}
|
||
|
||
// 打开网页
|
||
public void OpenUrlWithOsBrowser(string url)
|
||
{
|
||
try
|
||
{
|
||
Process.Start(url);
|
||
}
|
||
catch
|
||
{
|
||
ShowDialog("打开网页失败");
|
||
}
|
||
}
|
||
|
||
public static void StartUpgradeProcess(bool showFail = true)
|
||
{
|
||
try
|
||
{
|
||
string applicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
|
||
string path = Path.Combine(applicationBase, Path.GetFileName("updater.exe"));
|
||
ProcessStartInfo processStartInfo = new ProcessStartInfo()
|
||
{
|
||
WorkingDirectory = applicationBase,
|
||
FileName = path,
|
||
UseShellExecute = true,
|
||
Verb = "runas"
|
||
};
|
||
Process.Start(processStartInfo);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Logger.Error("启动升级程序失败", e);
|
||
if (showFail)
|
||
{
|
||
MessageBox.Show("启动升级程序失败,请重试");
|
||
}
|
||
}
|
||
}
|
||
|
||
public void StartProofread()
|
||
{
|
||
Globals.ThisAddIn.SendMessageToWeb("start", "login");
|
||
}
|
||
|
||
public void ShowCurrentPane()
|
||
{
|
||
Globals.ThisAddIn.ShowPanel();
|
||
}
|
||
public void HideCurrentPane()
|
||
{
|
||
Globals.ThisAddIn.HidePanel();
|
||
}
|
||
|
||
public void ShowLog(string message)
|
||
{
|
||
Logger.Info((Config.IS_WPS ? "WPS" : "WORD") + "-WEB " + message);
|
||
}
|
||
|
||
public void ShowLoginForm(string action)
|
||
{
|
||
Globals.ThisAddIn.ShowLoginForm(action);
|
||
}
|
||
public void ShowLexiconForm()
|
||
{
|
||
//Globals.ThisAddIn.ShowLoginForm(action);
|
||
(new FormLexicon()).Show();
|
||
}
|
||
public void Logout(string action)
|
||
{
|
||
// web同步注销到ribbon
|
||
Globals.ThisAddIn.SyncLogout();
|
||
|
||
if (string.IsNullOrEmpty(action) || action != "disabled-send")
|
||
{
|
||
// ribbon 发送注销动作到 web
|
||
Globals.ThisAddIn.SendMessageToWeb("logout", null);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 登录成功后通知后端
|
||
/// </summary>
|
||
public void loginSuccess(string userinfo)
|
||
{
|
||
if (userinfo == null || userinfo.Length == 0) return;
|
||
//
|
||
Userinfo info = JsonConvert.DeserializeObject<Userinfo>(userinfo);
|
||
// 登录成功 展示
|
||
Globals.ThisAddIn.ribbon.ProcessLoginInfo(info);
|
||
}
|
||
|
||
// 获取文档所有文本数据
|
||
public Dictionary<string, object> getAllText()
|
||
{
|
||
return Tools.GetAllText(Globals.ThisAddIn.Application.ActiveDocument);
|
||
}
|
||
public bool SaveDocument(int documentId)
|
||
{
|
||
var document = documentId > 0 ? Globals.ThisAddIn.GetDocumentById(documentId) : Globals.ThisAddIn.ActiveDocument;
|
||
try
|
||
{
|
||
document.Save();
|
||
return true;
|
||
}catch (Exception ex)
|
||
{
|
||
Logger.Error("保存文档失败", ex);
|
||
}
|
||
return false;
|
||
}
|
||
|
||
public bool Saved(int documentId)
|
||
{
|
||
var document = documentId > 0 ? Globals.ThisAddIn.GetDocumentById(documentId) : Globals.ThisAddIn.ActiveDocument;
|
||
return document.CurrentDocument.Saved;
|
||
}
|
||
|
||
public void Callback(string callbackId, string result)
|
||
{
|
||
Globals.ThisAddIn.GlobalCallback(callbackId, result);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 判断是否处理修订模式,如果没有在修订模式,则回调返回false
|
||
/// </summary>
|
||
/// <param name="documentId"></param>
|
||
/// <param name="callback"></param>
|
||
public void CheckInTrackRevisions(string message, int documentId, string callbackId)
|
||
{
|
||
var doc = documentId > 0 ? Globals.ThisAddIn.GetDocumentById(documentId) : Globals.ThisAddIn.ActiveDocument;
|
||
|
||
if (doc.CurrentDocument.TrackRevisions)
|
||
{
|
||
doc.RunInMainThread(() =>
|
||
{
|
||
var result = FormMessage.ShowMessage(message, "确认", "取消", null);
|
||
if (result == DialogResult.OK)
|
||
{
|
||
// 关闭修订模式
|
||
doc.CurrentDocument.TrackRevisions = false;
|
||
Callback(callbackId, "false");
|
||
}
|
||
else
|
||
{
|
||
Callback(callbackId, "true");
|
||
}
|
||
});
|
||
}
|
||
else
|
||
{
|
||
Callback(callbackId, "false");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取文档数据
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string getDocumentData(int documentId)
|
||
{
|
||
Dictionary<string, object> data = new Dictionary<string, object>();
|
||
var documentInfo = documentId > 0 ? Globals.ThisAddIn.GetDocumentById(documentId) : Globals.ThisAddIn.ActiveDocument;
|
||
|
||
var doc = documentInfo.CurrentDocument;
|
||
// 判断是否处理修订模式
|
||
if (doc.TrackRevisions)
|
||
{
|
||
var ret = MessageBox.Show("该文档已开启修订模型,请关闭此模式再进行校对。是否关闭?", "提示", MessageBoxButtons.YesNo);
|
||
if (ret == DialogResult.Yes)
|
||
{
|
||
doc.TrackRevisions = false;
|
||
}
|
||
else
|
||
{
|
||
data.Add("code", 1);
|
||
data.Add("message", "文档存在未处理的修订,请处理后再进行校对");
|
||
return Tools.GetJSONString(data);
|
||
}
|
||
}
|
||
// 判断是否需要强制升级
|
||
if (ShouldUpgradeForced())
|
||
{
|
||
data.Add("code", 2);
|
||
data.Add("message", "请先升级插件后再进行校对");
|
||
}
|
||
else if (doc.ProtectionType != WdProtectionType.wdNoProtection)
|
||
{
|
||
data.Add("code", 3);
|
||
data.Add("message", "文档受保护,请另存文档后再进行校对");
|
||
}
|
||
else if (doc.ReadOnly)
|
||
{
|
||
data.Add("code", 4);
|
||
data.Add("message", "文档无法编辑,请另存后再进行校对");
|
||
}
|
||
else
|
||
{
|
||
// 判断文档是否是只读模式
|
||
//FormMessage loadingDialog = null;
|
||
//// 大于15W字符无法校对
|
||
//Task.Run(() =>
|
||
//{
|
||
// if (doc.Characters.Count > 15 * 10000)
|
||
// {
|
||
// loadingDialog = Globals.ThisAddIn.ActiveDocument.ShowMessage("文档内容解析中,请稍候...", 0, false);
|
||
// }
|
||
//});
|
||
documentInfo.hasProcessMark = false;
|
||
data.Add("code", 0);
|
||
data.Add("message", "success");
|
||
data.Add("name", doc.Name);
|
||
//data.Add("documentId", Globals.ThisAddIn.ActiveDocument.Id);
|
||
data.Add("fullName", doc.FullName);
|
||
data.Add("documentId", GeIdBytDocument(doc));
|
||
data.Add("wordsCount", doc.Words.Count);
|
||
data.Add("charactersCount", doc.Characters.Count);
|
||
try
|
||
{
|
||
|
||
data.Add("content", Tools.GetAllText(doc));
|
||
}
|
||
catch (POIXMLException ex)
|
||
{
|
||
Logger.Error("校对文档格式有误或内容异常", ex);
|
||
data["code"] = 5;
|
||
data["message"] = "文档格式有误或内容异常,请另存文档后再进行校对";
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error("校对文档格式有误或内容异常", ex);
|
||
throw ex;
|
||
}
|
||
//if (loadingDialog != null && !loadingDialog.IsDisposed)
|
||
//{
|
||
// loadingDialog.Close();
|
||
//}
|
||
}
|
||
return Tools.GetJSONString(data);
|
||
}
|
||
|
||
public string GetDocumentInfo(int documentId)
|
||
{
|
||
Dictionary<string, object> data = new Dictionary<string, object>();
|
||
var documentInfo = documentId > 0 ? Globals.ThisAddIn.GetDocumentById(documentId) : Globals.ThisAddIn.ActiveDocument;
|
||
var doc = documentInfo.CurrentDocument;
|
||
data.Add("code", 0);
|
||
data.Add("message", "success");
|
||
data.Add("name", doc.Name);
|
||
//data.Add("documentId", Globals.ThisAddIn.ActiveDocument.Id);
|
||
data.Add("fullName", doc.FullName);
|
||
data.Add("documentId", GeIdBytDocument(doc));
|
||
data.Add("wordsCount", doc.Words.Count);
|
||
data.Add("charactersCount", doc.Characters.Count);
|
||
return Tools.GetJSONString(data);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据位置获取文档区域文本
|
||
/// </summary>
|
||
/// <param name="start">开始段落数</param>
|
||
/// <param name="end">数据段落书</param>
|
||
/// <returns></returns>
|
||
public string getParagraphTextByRange(int start, int end)
|
||
{
|
||
var list = Tools.GetTextListByParagraphRange(start, end);
|
||
return Tools.GetJSONString(list);
|
||
}
|
||
|
||
public string GetDocumentAllText()
|
||
{
|
||
return Globals.ThisAddIn.ActiveDocument.GetAllText();
|
||
}
|
||
public string GetTextByRange(int start, int end)
|
||
{
|
||
var range = Globals.ThisAddIn.ActiveDocument.Range(start, end);
|
||
if (range == null)
|
||
{
|
||
return JSONObject.Create()
|
||
.Put("text", null)
|
||
.Put("page", -1)
|
||
.Put("line", -1)
|
||
.ToString();
|
||
}
|
||
var text = Globals.ThisAddIn.ActiveDocument.GetRangeText(range);
|
||
|
||
// 获取书签在文档的页码数
|
||
var pageNumber = range.get_Information(WdInformation.wdActiveEndPageNumber);
|
||
// 获取书签在当前页面的行数
|
||
var lineNumber = range.get_Information(WdInformation.wdFirstCharacterLineNumber);
|
||
|
||
return JSONObject.Create()
|
||
.Put("text", text)
|
||
.Put("page", pageNumber)
|
||
.Put("line", lineNumber)
|
||
.ToString();
|
||
}
|
||
/// <summary>
|
||
/// 获取文档所有段落文本
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string getAllParagraphs()
|
||
{
|
||
var doc = Globals.ThisAddIn.ActiveDocument;
|
||
if (doc == null)
|
||
{
|
||
return "";
|
||
}
|
||
return Tools.GetJSONString(doc.GetAllParagraphs());
|
||
}
|
||
|
||
|
||
public void getParagraphTextByRangeSync(int start, int end)
|
||
{
|
||
Task.Run(() =>
|
||
{
|
||
var list = Tools.GetTextListByParagraphRange(start, end);
|
||
Globals.ThisAddIn.SendMessageToWeb("getParagraphTextByRange", Tools.GetJSONString(list));
|
||
});
|
||
}
|
||
|
||
public int getTotalParagraphNumber() => Globals.ThisAddIn.ActiveDocument?.GetTotalParagraphNumber() ?? -1;
|
||
|
||
/// <summary>
|
||
/// 读取文档原始文件并转换成base64
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string getDocumentFileData() => Globals.ThisAddIn.ActiveDocument?.GetOriginFileData() ?? "";
|
||
|
||
public void ShowUpgrade(string data, bool force = false)
|
||
{
|
||
Globals.ThisAddIn.ActiveDocument.ShowUpgrade(data, force);
|
||
}
|
||
|
||
public void noticeOtherWeb(string json, string targetWebName)
|
||
{
|
||
if (targetWebName != null)
|
||
{
|
||
if (webViewDict.ContainsKey(targetWebName))
|
||
{
|
||
SendMessageToWeb(webViewDict[targetWebName], json);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 如果没有指定 则向所有 webview 发送消息
|
||
foreach (var item in webViewDict)
|
||
{
|
||
SendMessageToWeb(item.Value, json);
|
||
}
|
||
}
|
||
}
|
||
|
||
private void SendMessageToWeb(WebView2 webView, string json)
|
||
{
|
||
webView.CoreWebView2.PostWebMessageAsJson(json);
|
||
}
|
||
|
||
public async static void InitWebEnvAsync(string name, WebView2 webView)
|
||
{
|
||
try
|
||
{
|
||
webView.Name = name;
|
||
if (webViewDict.ContainsKey(webView.Name))
|
||
{
|
||
webViewDict[name] = webView;
|
||
}
|
||
else
|
||
{
|
||
webViewDict.Add(name, webView);
|
||
}
|
||
|
||
Logger.Debug("初始化Main Pane Web环境 开始");
|
||
// 禁用web安全,允许跨域 否则需要web编译为umd加载模式
|
||
var ops = new CoreWebView2EnvironmentOptions("--disable-web-security");
|
||
var env = await CoreWebView2Environment.CreateAsync(null, Config.WEB_DATA_PATH, ops);
|
||
await webView.EnsureCoreWebView2Async(env);
|
||
// 添加 js与客户端代理
|
||
|
||
webView.CoreWebView2.AddHostObjectToScript("bridge", bridge);
|
||
Logger.Debug("初始化Main Pane Web环境 结束");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Debug.WriteLine("初始化web环境失败" + ex.Message);
|
||
Logger.Error("初始化web环境失败", ex);
|
||
//LogHelper.Log(ex);
|
||
}
|
||
}
|
||
|
||
|
||
public void clearAllProofreadMarkById(int documentId) => Globals.ThisAddIn.GetDocumentById(documentId)?.ClearAllProofreadMark();
|
||
public void ClearCurrentDocumentMarks() => Globals.ThisAddIn.ActiveDocument?.ClearAllProofreadMark();
|
||
public void removeBookmark(string markId) => DocumentUtil.RemoveBookmark(markId);
|
||
|
||
/// <summary>
|
||
/// 获取设备ID
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string GetDeviceId()
|
||
{
|
||
return Config.DeviceId;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置帮助文档地址
|
||
/// </summary>
|
||
/// <param name="url"></param>
|
||
public void SetHelpUrl(string url) => Config.USER_MANUAL_URL = url;
|
||
|
||
public string getAllBookmark()
|
||
{
|
||
return ToJSON(DocumentUtil.GetAllBookmark());
|
||
}
|
||
public string getSectionText()
|
||
{
|
||
return ToJSON(DocumentUtil.GetSectionText());
|
||
}
|
||
|
||
private static string ToJSON(object data)
|
||
{
|
||
return JsonConvert.SerializeObject(data);
|
||
}
|
||
|
||
public string GetCheckText()
|
||
{
|
||
var document = Globals.ThisAddIn.Application.ActiveDocument;
|
||
int count = Globals.ThisAddIn.Application.ActiveDocument.Paragraphs.Count;
|
||
if (count > 10000)
|
||
{
|
||
return document.Content.Text;
|
||
}
|
||
string text = "";
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
string input = document.Paragraphs[i + 1].Range.Text.Replace("\f\r", "");
|
||
string pattern = "[\\r\\f\\n]";
|
||
string replacement = "\t";
|
||
string text2 = Regex.Replace(input, pattern, replacement);
|
||
if (text2.EndsWith("\t"))
|
||
{
|
||
text2 = text2.Substring(0, text2.Length - 1);
|
||
}
|
||
text2 += "\r";
|
||
text += text2;
|
||
}
|
||
return text;
|
||
}
|
||
|
||
public string GetSelectedText()
|
||
{
|
||
// 文档对象
|
||
var document = Globals.ThisAddIn.Application.ActiveDocument;
|
||
// 获取选区
|
||
var selection = Globals.ThisAddIn.Application.Selection;
|
||
// 段落数
|
||
int count = selection.Paragraphs.Count;
|
||
if (count > 10000)
|
||
{
|
||
return selection.Text;
|
||
}
|
||
string text = "";
|
||
if (count == 1)
|
||
{
|
||
string input = selection.Text.Replace("\f\r", "");
|
||
string pattern = "[\\r\\f\\n]";
|
||
string replacement = "\t";
|
||
string text2 = Regex.Replace(input, pattern, replacement);
|
||
return text + text2;
|
||
}
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
string input;
|
||
if (i == 0)
|
||
{
|
||
int start = selection.Range.Start;
|
||
int end = selection.Paragraphs[i + 1].Range.End;
|
||
Document obj = document;
|
||
object Start = start;
|
||
object End = end;
|
||
input = obj.Range(ref Start, ref End).Text;
|
||
}
|
||
else if (i == count - 1)
|
||
{
|
||
int start2 = selection.Paragraphs[i + 1].Range.Start;
|
||
int end2 = selection.Range.End;
|
||
Document obj2 = document;
|
||
object End = start2;
|
||
object Start = end2;
|
||
input = obj2.Range(ref End, ref Start).Text;
|
||
}
|
||
else
|
||
{
|
||
input = selection.Paragraphs[i + 1].Range.Text;
|
||
}
|
||
input = input.Replace("\f\r", "");
|
||
string pattern2 = "[\\r\\f\\n]";
|
||
string replacement2 = "\t";
|
||
string text3 = Regex.Replace(input, pattern2, replacement2);
|
||
if (text3.EndsWith("\t"))
|
||
{
|
||
text3 = text3.Substring(0, text3.Length - 1);
|
||
}
|
||
text3 += "\r";
|
||
text += text3;
|
||
}
|
||
return text;
|
||
}
|
||
public void ShowSettingForm()
|
||
{
|
||
Globals.ThisAddIn.ActiveDocument.ShowSetting();
|
||
}
|
||
|
||
public void ShowWebView(string url, int width, int height, bool dialog)
|
||
{
|
||
Globals.ThisAddIn.ActiveDocument.ShowWebView(url, width, height, dialog);
|
||
}
|
||
|
||
public void MoveCursor(int pos)
|
||
{
|
||
var rng = Globals.ThisAddIn.Application.ActiveDocument.Range(pos, pos);
|
||
rng.Select();
|
||
}
|
||
|
||
public void SelectMarkById(int proofreadId, int documentId)
|
||
{
|
||
|
||
Globals.ThisAddIn.ActiveDocument?.SelectMarkById(proofreadId, false);
|
||
}
|
||
|
||
public void processMark(int proofreadId, int status)
|
||
{
|
||
Globals.ThisAddIn.ActiveDocument?.ProcessMark(proofreadId, status);
|
||
}
|
||
public string InitContent(string content, int documentId)
|
||
{
|
||
return InitContent(content, documentId, true);
|
||
}
|
||
public string InitContent(string content, int documentId, bool clearOriginMark)
|
||
{
|
||
try
|
||
{
|
||
// 根据文档编号 获取当前文档避免数据混乱
|
||
var document = documentId < 1 ? Globals.ThisAddIn.ActiveDocument : (Globals.ThisAddIn.GetDocumentById(documentId) ?? throw new Exception("没有找到校对文档对象"));
|
||
|
||
// 先清除所有数据
|
||
if (clearOriginMark) document.ClearAllProofreadMark();
|
||
List<CorrectContext> list = JsonConvert.DeserializeObject<List<CorrectContext>>(content);
|
||
document.InitProofread(list);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error("Initial Content error:", ex);
|
||
return "false";
|
||
}
|
||
return "true";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新增校对项 查找时的偏移量
|
||
/// </summary>
|
||
//private static readonly int INSERT_FIND_OFFSET = 5;
|
||
|
||
public string MarkSentence(string content, int documentId)
|
||
{
|
||
// 初始化话
|
||
return InitContent(content, documentId, false);
|
||
}
|
||
|
||
public void ShowMessage(string message, int closeDelay = 1000, bool showCloseBtn = true)
|
||
{
|
||
//FormMessage.ShowMessage(message, closeDelay);
|
||
Globals.ThisAddIn.ActiveDocument?.ShowMessage(message, closeDelay, showCloseBtn);
|
||
}
|
||
public void ShowConfirmMessage(string message, string confirmText, string confirmAction)
|
||
{
|
||
Globals.ThisAddIn.ActiveDocument.ShowDialog(message, confirmText, confirmAction);
|
||
}
|
||
public string ShowDialogMessage(string message)
|
||
{
|
||
var result = FormMessage.ShowMessage(message, "确认", null);
|
||
if (result == DialogResult.Retry)
|
||
{
|
||
return "retry";
|
||
}
|
||
return "ok";
|
||
}
|
||
|
||
// 保存文件
|
||
public void WriteText(string content, string filename, string callbackId)
|
||
{
|
||
Globals.ThisAddIn.ActiveDocument.RunInMainThread(() =>
|
||
{
|
||
var json = JSONObject.Create();
|
||
try
|
||
{
|
||
string currentName = Globals.ThisAddIn.Application.ActiveDocument.Name;
|
||
// 去掉文件名后缀
|
||
currentName = currentName.Substring(0, currentName.LastIndexOf("."));
|
||
SaveFileDialog sfd = new SaveFileDialog
|
||
{
|
||
// 设置默认文件名
|
||
FileName = filename,
|
||
Filter = "文本文件|*.txt"
|
||
};
|
||
|
||
var result = sfd.ShowDialog();
|
||
// 如果用户取消选择,则返回
|
||
if (result != DialogResult.Cancel)
|
||
{
|
||
if (File.Exists(sfd.FileName))
|
||
{
|
||
File.Delete(sfd.FileName);
|
||
}
|
||
File.WriteAllText(sfd.FileName, content);
|
||
json.Put("status", "success");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
json.Put("status", "error").Put("message", ex.Message);
|
||
}
|
||
Globals.ThisAddIn.GlobalCallback(
|
||
callbackId,
|
||
json.ToString()
|
||
);
|
||
});
|
||
//
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导出勘误表
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string ExportProofreadResult(string modelType)
|
||
{
|
||
try
|
||
{
|
||
Globals.ThisAddIn.ActiveDocument.ExportResult(modelType);
|
||
return BridgeResult.Success();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error("导出勘误表失败:" + ex.Message, ex);
|
||
return BridgeResult.Error(-1, ex.Message);
|
||
}
|
||
}
|
||
|
||
public string ReadText(string path)
|
||
{
|
||
try
|
||
{
|
||
if (!File.Exists(path)) return BridgeResult.Error(-1, "文件不存在");
|
||
return BridgeResult.Success(File.ReadAllText(path));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error("读取文件失败:" + ex.Message, ex);
|
||
return BridgeResult.Error(-1, ex.Message);
|
||
}
|
||
}
|
||
|
||
public void Focus()
|
||
{
|
||
// 使面板重新获取到焦点
|
||
Globals.ThisAddIn.ActiveDocument.FocusToPanel();
|
||
}
|
||
|
||
public string GetProofreadOriginData()
|
||
{
|
||
return Tools.GetJSONString(Globals.ThisAddIn.ActiveDocument.GetProofreadOriginData());
|
||
}
|
||
|
||
public string SaveCache(int documentId, string cache, bool silent)
|
||
{
|
||
var document = Globals.ThisAddIn.GetDocumentById(documentId);
|
||
if (document == null)
|
||
{
|
||
return BridgeResult.Success("ok");
|
||
}
|
||
if (!silent)
|
||
{
|
||
if (!document.CurrentDocument.Saved)
|
||
{
|
||
MessageBox.Show("请先保存文档");
|
||
return BridgeResult.Error(1, "请先保存文档");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 静默时 自动保存文档
|
||
document.Save();
|
||
}
|
||
try
|
||
{
|
||
Logger.Debug("SaveCache " + document.fileName + " used " + document.ProofreadCachePath);
|
||
|
||
if (File.Exists(document.ProofreadCachePath))
|
||
{
|
||
File.Delete(document.ProofreadCachePath);
|
||
}
|
||
File.WriteAllText(document.ProofreadCachePath, cache);
|
||
// 对缓存文件进行隐藏
|
||
File.SetAttributes(document.ProofreadCachePath, FileAttributes.Hidden);
|
||
return BridgeResult.Success("ok");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error("保存缓存失败:" + ex.Message, ex);
|
||
return BridgeResult.Error(-1, ex.Message);
|
||
}
|
||
}
|
||
|
||
public bool CacheExists(int documentId)
|
||
{
|
||
var document = Globals.ThisAddIn.GetDocumentById(documentId);
|
||
return File.Exists(document.ProofreadCachePath);
|
||
}
|
||
|
||
public string LoadCache()
|
||
{
|
||
var document = Globals.ThisAddIn.ActiveDocument;
|
||
if (!File.Exists(document.ProofreadCachePath))
|
||
{
|
||
return BridgeResult.Error(1, "cache-not-exists");
|
||
}
|
||
Logger.Info("Load cache " + document.fileName + " used " + document.ProofreadCachePath);
|
||
try
|
||
{
|
||
return BridgeResult.Success(File.ReadAllText(document.ProofreadCachePath));
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error("加载缓存失败:" + ex.Message, ex);
|
||
return BridgeResult.Error(ex.Message);
|
||
}
|
||
}
|
||
|
||
public bool DeleteCache()
|
||
{
|
||
try
|
||
{
|
||
if (File.Exists(Globals.ThisAddIn.ActiveDocument.ProofreadCachePath))
|
||
{
|
||
File.Delete(Globals.ThisAddIn.ActiveDocument.ProofreadCachePath);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error("删除缓存失败:" + ex.Message, ex);
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
public string ShowConfirm(string message, string caption, string yesButtonText, string noButtonText)
|
||
{
|
||
var result = FormDialog.Show(message, caption, yesButtonText, noButtonText);
|
||
|
||
return BridgeResult.Success(result == DialogResult.Yes ? "yes" : "no");
|
||
}
|
||
|
||
public string InitProofreadCacheList(string content, string originData)
|
||
{
|
||
try
|
||
{
|
||
List<CorrectContext> list = JsonConvert.DeserializeObject<List<CorrectContext>>(content);
|
||
Dictionary<int, ProofreadRangeInfo> dics = string.IsNullOrEmpty(originData) ? null : JsonConvert.DeserializeObject<Dictionary<int, ProofreadRangeInfo>>(originData);
|
||
Globals.ThisAddIn.InitProofreadCacheList(list, dics);
|
||
return BridgeResult.Success();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Error("初始化缓存失败:" + ex.Message, ex);
|
||
return BridgeResult.Error(ex);
|
||
}
|
||
}
|
||
|
||
public void SetCurrentDocumentProofreadStatus(int documentId, bool proofread, bool proofreading, bool checkIsActive = false)
|
||
{
|
||
if (documentId < 1) return;
|
||
var document = Globals.ThisAddIn.GetDocumentById(documentId);
|
||
if (document != null)
|
||
{
|
||
document.Proofread = proofread;
|
||
document.Proofreading = proofreading;
|
||
if (checkIsActive && documentId != Globals.ThisAddIn.ActiveDocument.Id) return;
|
||
document.CheckBtnStatus();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置当前文档的校对状态
|
||
/// </summary>
|
||
/// <param name="documentId"></param>
|
||
/// <param name="proofread"></param>
|
||
/// <param name="proofreading"></param>
|
||
public void SetCurrentDocumentProofreadStatus(int documentId, bool proofread, bool proofreading)
|
||
{
|
||
SetCurrentDocumentProofreadStatus(documentId, proofread, proofreading, false);
|
||
}
|
||
}
|
||
}
|