using AIProofread.Controls; using Microsoft.Office.Interop.Word; using Microsoft.Office.Tools.Word; using Microsoft.Web.WebView2.Core; using Microsoft.Web.WebView2.WinForms; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Runtime.Remoting.Contexts; using System.Text; using System.Text.RegularExpressions; using System.Windows.Forms; using System.Xml.Linq; using UtilLib; using static System.Windows.Forms.VisualStyles.VisualStyleElement.Header; using static System.Windows.Forms.VisualStyles.VisualStyleElement.TaskbarClock; using Document = Microsoft.Office.Interop.Word.Document; 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 webViewDict = new Dictionary(); private static readonly Dictionary> eventHandlers = new Dictionary>(); private static readonly Dictionary marks = new Dictionary(); private static int selectProofreadId = -1; private static object missing = System.Reflection.Missing.Value; public string GetAppVersion() { return Config.APP_VERSION; } public void showDialog(string message) { System.Windows.Forms.MessageBox.Show(message); } public int getMinWIdth() { return Globals.ThisAddIn.GetMinWidth(); } /// /// 添加事件 /// /// /// public static void AddEventHandler(BridgeEvent eventName, BridgeEventHandler handler) { if (!eventHandlers.ContainsKey(eventName)) { eventHandlers.Add(eventName, new List()); } eventHandlers[eventName].Add(handler); } public static void RemoveEventHandler(BridgeEvent eventName, BridgeEventHandler handler) { if (eventHandlers.ContainsKey(eventName)) { eventHandlers[eventName].Remove(handler); } } // 打开网页 public void OpenUrlWithOsBrowser(string url) { try { Process.Start(url); } catch { showDialog("打开网页失败"); } } public void StartProofread() { Globals.ThisAddIn.SendMessageToWeb("start", "login"); } public void ShowCurrentPane() { Globals.ThisAddIn.currentDocumentTaskPane.Visible = true; } public void HideCurrentPane() { Globals.ThisAddIn.currentDocumentTaskPane.Visible = false; } public void Logout(string action) { if (action == "async-info") { // web同步注销到ribbon Globals.ThisAddIn.SyncLogout(); } else { // ribbon 发送注销动作到 web Globals.ThisAddIn.SendMessageToWeb("logout", null); } } /// /// 登录成功后通知后端 /// public void loginSuccess(string userinfo) { if (userinfo == null || userinfo.Length == 0) return; // Userinfo info = JsonConvert.DeserializeObject(userinfo); // 登录成功 展示 Globals.ThisAddIn.ribbon.ProcessLoginInfo(info); //Globals.ThisAddIn.SendMessageToWeb("async-login-success", null); } // 获取文档所有文本数据 public Dictionary getAllText() { return Tools.GetAllText(); } public string getDocumentData() { Dictionary data = new Dictionary(); var name = Globals.ThisAddIn.Application.ActiveDocument.Name; data.Add("name", name); data.Add("fullName", Globals.ThisAddIn.Application.ActiveDocument.FullName); data.Add("content", Tools.GetAllText()); return Tools.GetJSONString(data); } public void ShowUpgrade(string data) { var upgradeData = JsonConvert.DeserializeObject(data); var ret = System.Windows.Forms.MessageBox.Show(upgradeData.Message, "更新提示", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question); if (ret == System.Windows.Forms.DialogResult.Yes) { OpenUrlWithOsBrowser(upgradeData.DownloadUrl); } } 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) { webView.Name = name; if (webViewDict.ContainsKey(webView.Name)) { webViewDict[name] = webView; } else { webViewDict.Add(name, webView); } // 禁用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); //webView.CoreWebView2.Settings.AreDevToolsEnabled = false; //webView.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled = false; //webView.CoreWebView2.Settings.AreHostObjectsAllowed = true; // 添加 js与客户端代理 webView.CoreWebView2.AddHostObjectToScript("bridge", bridge); } // 清除所有标记 public void clearAllProofreadMark() { try { selectProofreadId = -1; foreach (var item in marks.Values) { if (item.mark != null && item.content.tag == "i" && item.content.isAccept == AcceptStatus.Default) { item.mark.Text = ""; } } marks.Clear(); DocumentUtil.ClearProofreadMarks(); }catch (Exception ex) { Logger.Log("ClearAllProofreadMark",ex); } } public void removeBookmark(string markId) { DocumentUtil.RemoveBookmark(markId); } public void addBookmark(string data) { var item = JsonConvert.DeserializeObject(data); //var mark = DocumentUtil.AddBookmark(item.color, item.start, item.end); // 初始化校对对象 marks.Add(item.id, new ProofreadItem(item)); } 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 vstoDocument = Globals.Factory.GetVstoObject(document); // 获取选区 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 ShowLoginForm(string action) { Globals.ThisAddIn.ShowLoginForm(action); } public void ShowSettingForm() { FormSetting frm = new FormSetting(); frm.Show(); } public void MoveCursor(int pos) { var rng = Globals.ThisAddIn.Application.ActiveDocument.Range(pos, pos); rng.Select(); } public void SelectMarkById(int proofreadId) { if (proofreadId == selectProofreadId) return; var doc = Globals.ThisAddIn.Application.ActiveDocument; // 取消上一个标签移除 if (selectProofreadId > 0 && marks.ContainsKey(selectProofreadId)) { var m = marks[selectProofreadId]; if (doc.Bookmarks.Exists(m.Name)) { marks[selectProofreadId].UnSelect(); } else { marks.Remove(selectProofreadId); } } selectProofreadId = proofreadId; if (proofreadId > 0 && marks.ContainsKey(proofreadId)) { var mark = marks[proofreadId].mark; // 已经不存在该标签了 if (!doc.Bookmarks.Exists(mark.Name)) { marks.Remove(selectProofreadId); return; } //object lineNum = (int)mark.Range.Information[WdInformation.wdFirstCharacterLineNumber] - 1; //object goToLine = WdGoToItem.wdGoToLine; //object goNext = WdGoToDirection.wdGoToNext; //Globals.ThisAddIn.Application.ActiveWindow.Selection.GoTo(ref goToLine, ref goNext, ref lineNum); // object bookmark = WdGoToItem.wdGoToBookmark; object bookmarkName = mark.Name; //doc.GoTo(mark); //mark.Range.GoTo(); Globals.ThisAddIn.Application.ActiveWindow.Selection.GoTo(ref bookmark, ref missing, ref missing, ref bookmarkName); // //mark.DisableCharacterSpaceGrid = false; // 先滚动到可视区域 //doc.ActiveWindow.ScrollIntoView(mark.Range); marks[proofreadId].Select(); Globals.ThisAddIn.SendMessageToWeb("select", proofreadId); } Globals.ThisAddIn.SendMessageToWeb("select_proofread", proofreadId); } public void processMark(int proofreadId, int status) { if (proofreadId > 0 && marks.ContainsKey(proofreadId)) { marks[proofreadId].Process(status); } } public void InitContent(string content) { List list = JsonConvert.DeserializeObject>(content); // 先清除所有数据 clearAllProofreadMark(); //var app = Globals.ThisAddIn.Application; //var cur = app.Selection; // foreach (var correct in list) { //cur.TypeText(correct.Insert); //var rng = cur.Range; if (correct.Diffs != null && correct.Diffs.Count > 0) { //var diffs = correct.Diffs.OrderBy(it => //{ // if (it.tag != "i") return it.start; // return it.start + correct.Insert_len; //}).ToList(); int index = 0; foreach (var item in correct.Diffs) { var mark = AddBookmark(item, index, correct.Offset, correct.Insert_len); if (item.tag != "i") index++; if (mark != null) { marks.Add(item.id, new ProofreadItem(item, mark)); } } } } foreach (var item in marks) { if(item.Value.mark != null) { if (item.Value.content.tag == "i") { item.Value.mark.Text = ToolUtil.GetBlankText(item.Value.content.text.Length); } if (item.Value.content.color != null) { // 给选区添加背景颜色 item.Value.mark.Shading.BackgroundPatternColor = (WdColor)ColorTranslator.ToOle(Colors.FromHex(item.Value.content.color)); } } } } public Microsoft.Office.Tools.Word.Bookmark AddBookmark(CorrectedContent item, int findIndex, int offset, int length) { Microsoft.Office.Tools.Word.Bookmark bookmark = null; try { var document = Globals.ThisAddIn.Application.ActiveDocument; ControlCollection controls = Globals.Factory.GetVstoObject(document).Controls; var Start = offset; var End = offset + length - 1; // 整体选区的内容 var fullRange = document.Range(Start, End); string fullText = fullRange.Text; End = offset + item.start; Start = offset + item.end; var r = document.Range(End, Start); var markName = Config.BuildBookmarkName(item.id); // 判断是否已经存在 if (controls.Contains(markName)) { controls.Remove(markName); } // 判断选区是否正确 if (item.tag == "i" || r.Text == item.origin) { bookmark = controls.AddBookmark(r, markName); bookmark.Tag = "ai_proofread"; } else { int startPos = 0, index, findCount = 0; while ((index = fullText.IndexOf(item.origin, startPos)) != -1) { if (findCount == findIndex) { r = document.Range(offset + index, offset + index + item.origin.Length); bookmark = controls.AddBookmark(r, markName); bookmark.Tag = "ai_proofread"; break; } startPos = index; findCount++; } } } catch (Exception ex) { Logger.Log("create mark error:" + ex.Message + "\n" + ex.StackTrace + "\n\n"); } return bookmark; } } }