993 lines
36 KiB
C#
993 lines
36 KiB
C#
using AIProofread.Controls;
|
||
using AIProofread.core;
|
||
using AIProofread.Util;
|
||
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.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 void ShowUpgradeView()
|
||
{
|
||
var needUpgrade = CurrentUpgrade.NeedUpgrade(Config.APP_VERSION);
|
||
if (CurrentUpgrade.Ext == 1)
|
||
{
|
||
if (!needUpgrade)
|
||
{
|
||
showDialog("当前版本为最新版本,无需升级");
|
||
}
|
||
else
|
||
{
|
||
var ret = MessageBox.Show(CurrentUpgrade.Message, "是否确认更新", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question);
|
||
if (ret == DialogResult.Yes)
|
||
{
|
||
OpenUrlWithOsBrowser(CurrentUpgrade.DownloadUrl);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
StartUpgradeProcess();
|
||
}
|
||
}
|
||
|
||
public bool ShouldUpgradeForced()
|
||
{
|
||
return CurrentUpgrade != null && CurrentUpgrade.NeedUpgrade(Config.APP_VERSION) && CurrentUpgrade.UpgradeType == 1;
|
||
}
|
||
|
||
public void InitPluginUpgrade()
|
||
{
|
||
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())
|
||
//{
|
||
// // 显示升级框
|
||
// ShowUpgradeView();
|
||
//}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Log(ex);
|
||
}
|
||
}
|
||
|
||
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();
|
||
}
|
||
|
||
/// <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.documentIdDics[document] = id;
|
||
}
|
||
public Document GetDocumentById(int id)
|
||
{
|
||
//return GeIdBytDocument(Globals.ThisAddIn.Application.ActiveDocument);
|
||
var documentDic = Globals.ThisAddIn.documentIdDics;
|
||
foreach (var doc in documentDic.Keys)
|
||
{
|
||
if (documentDic[doc] == id) return doc;
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public int GetCurrentDocumentId()
|
||
{
|
||
return GeIdBytDocument(Globals.ThisAddIn.Application.ActiveDocument);
|
||
}
|
||
|
||
public int GeIdBytDocument(Document document)
|
||
{
|
||
if (Globals.ThisAddIn.documentIdDics.ContainsKey(document))
|
||
{
|
||
return Globals.ThisAddIn.documentIdDics[document];
|
||
}
|
||
//int id = Globals.ThisAddIn.documentIdDics.Count + 1;
|
||
//// 设置文档编号
|
||
//SetCurrentDocumentId((int)id);
|
||
//return id ;
|
||
return 0;
|
||
}
|
||
|
||
// 打开网页
|
||
public void OpenUrlWithOsBrowser(string url)
|
||
{
|
||
try
|
||
{
|
||
Process.Start(url);
|
||
}
|
||
catch
|
||
{
|
||
showDialog("打开网页失败");
|
||
}
|
||
}
|
||
|
||
public static void StartUpgradeProcess()
|
||
{
|
||
try
|
||
{
|
||
string applicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
|
||
string path = "updater.exe";
|
||
ProcessStartInfo processStartInfo = new ProcessStartInfo(Path.Combine(applicationBase, Path.GetFileName(path)))
|
||
{
|
||
WorkingDirectory = applicationBase,
|
||
};
|
||
Process.Start(processStartInfo);
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Logger.Log(e);
|
||
MessageBox.Show("启动升级程序失败,请重试");
|
||
}
|
||
}
|
||
|
||
public void StartProofread()
|
||
{
|
||
Globals.ThisAddIn.SendMessageToWeb("start", "login");
|
||
}
|
||
|
||
public void ShowCurrentPane()
|
||
{
|
||
Globals.ThisAddIn.ShowPanel();
|
||
//Globals.ThisAddIn.currentDocumentTaskPane.Visible = true;
|
||
}
|
||
public void HideCurrentPane()
|
||
{
|
||
Globals.ThisAddIn.HidePanel();
|
||
//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);
|
||
}
|
||
}
|
||
|
||
/// <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);
|
||
//Globals.ThisAddIn.SendMessageToWeb("async-login-success", null);
|
||
}
|
||
|
||
// 获取文档所有文本数据
|
||
public Dictionary<string, object> getAllText()
|
||
{
|
||
return Tools.GetAllText(Globals.ThisAddIn.Application.ActiveDocument);
|
||
}
|
||
public string getDocumentData()
|
||
{
|
||
|
||
Dictionary<string, object> data = new Dictionary<string, object>();
|
||
var doc = Globals.ThisAddIn.Application.ActiveDocument;
|
||
|
||
if (!doc.Saved)
|
||
{
|
||
data.Add("code", 1);
|
||
data.Add("message", "请保存文档后再进行校对");
|
||
}
|
||
else if (ShouldUpgradeForced())
|
||
{
|
||
data.Add("code", 2);
|
||
data.Add("message", "请升级插件后再进行校对");
|
||
}
|
||
else if (doc.ProtectionType != WdProtectionType.wdNoProtection)
|
||
{
|
||
data.Add("code", 3);
|
||
data.Add("message", "文档受保护,无法编辑");
|
||
}
|
||
else
|
||
{
|
||
data.Add("code", 0);
|
||
data.Add("message", "success");
|
||
data.Add("name", doc.Name);
|
||
data.Add("fullName", doc.FullName);
|
||
//data.Add("documentId", GeIdBytDocument(doc));
|
||
data.Add("wordsCount", doc.Words.Count);
|
||
data.Add("charactersCount", doc.Characters.Count);
|
||
data.Add("content", Tools.GetAllText(doc));
|
||
}
|
||
return Tools.GetJSONString(data);
|
||
}
|
||
|
||
|
||
public string getParagraphTextByRange(int start, int end)
|
||
{
|
||
var list = Tools.GetTextListByParagraphRange(start, end);
|
||
return Tools.GetJSONString(list);
|
||
}
|
||
|
||
public string getAllParagraphs()
|
||
{
|
||
var doc = Globals.ThisAddIn.Application.ActiveDocument;
|
||
|
||
var rangeText = doc.Content.Text;
|
||
var trimText = HostHelper.ReplaceSpecialChars(rangeText, isReplaceMultSpaceLine: true);
|
||
|
||
string[] separator = new string[5] { "\r\a", "\a", "\r", "\v", "\f" };
|
||
string[] array4 = rangeText.Split(separator, StringSplitOptions.None);
|
||
string[] array5 = trimText.Split('\n');
|
||
List<string> list = new List<string>();
|
||
var paragraphs = doc.Paragraphs;
|
||
int total = paragraphs.Count;
|
||
for (int i = 1; i <= total; i++)
|
||
{
|
||
list.Add(GetParagraphText(paragraphs[i]));
|
||
}
|
||
var array6 = list.ToArray();
|
||
Dictionary<string, object> data = new Dictionary<string, object>
|
||
{
|
||
{"origin_cut",array4 },
|
||
{"trim_cut",array5 },
|
||
{"paragraph_cut",array6 },
|
||
};
|
||
return Tools.GetJSONString(data);
|
||
}
|
||
private string GetParagraphText(Paragraph paragraph)
|
||
{
|
||
// 需要
|
||
return GetRangeText(paragraph.Range);
|
||
}
|
||
private string GetRangeText(Range range)
|
||
{
|
||
// 需要
|
||
return range.Text;
|
||
}
|
||
|
||
|
||
public void getParagraphTextByRangeSync(int start, int end)
|
||
{
|
||
//var list = Tools.GetTextListByParagraphRange(start, end);
|
||
//return Tools.GetJSONString(list);
|
||
Task.Run(() =>
|
||
{
|
||
var list = Tools.GetTextListByParagraphRange(start, end);
|
||
Globals.ThisAddIn.SendMessageToWeb("getParagraphTextByRange", Tools.GetJSONString(list));
|
||
});
|
||
}
|
||
|
||
public int getTotalParagraphNumber()
|
||
{
|
||
return Globals.ThisAddIn.Application.ActiveDocument.Paragraphs.Count;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取文档原始文件并转换成base64
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string getDocumentFileData()
|
||
{
|
||
var doc = Globals.ThisAddIn.Application.ActiveDocument.FullName;
|
||
FileStream fs = new FileStream(doc, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||
byte[] bytes = new byte[fs.Length];
|
||
fs.Read(bytes, 0, bytes.Length);
|
||
return Convert.ToBase64String(bytes);
|
||
}
|
||
|
||
public void ShowUpgrade(string data)
|
||
{
|
||
//var upgradeData = JsonConvert.DeserializeObject<UpgradeData>(data);
|
||
//var needUpgrade = upgradeData.NeedUpgrade(Config.APP_VERSION);
|
||
//if (upgradeData.Ext == 1)
|
||
//{
|
||
// if (!needUpgrade)
|
||
// {
|
||
// showDialog("当前版本为最新版本,无需升级");
|
||
// }
|
||
// else
|
||
// {
|
||
// var ret = MessageBox.Show(upgradeData.Message, "是否确认更新", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question);
|
||
// if (ret == DialogResult.Yes)
|
||
// {
|
||
// OpenUrlWithOsBrowser(upgradeData.DownloadUrl);
|
||
// }
|
||
// }
|
||
//}
|
||
//else
|
||
//{
|
||
// StartUpgradeProcess();
|
||
//}
|
||
}
|
||
|
||
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);
|
||
}
|
||
|
||
// 禁用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);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Log(ex);
|
||
}
|
||
}
|
||
|
||
|
||
public void clearAllProofreadMarkById(int documentId)
|
||
{
|
||
clearAllProofreadMark(GetDocumentById(documentId));
|
||
}
|
||
// 清除所有标记
|
||
public void clearAllProofreadMark(Document document)
|
||
{
|
||
// 标记当前文档所有书签数据
|
||
Globals.ThisAddIn.ActiveCurrentDocumentMarks(document);
|
||
try
|
||
{
|
||
selectProofreadId = -1;
|
||
foreach (var item in marks.Values)
|
||
{
|
||
if (item.mark != null)
|
||
{
|
||
if (item.content.tag == "i" && item.content.isAccept == AcceptStatus.Default)
|
||
{
|
||
item.mark.Text = "";
|
||
}
|
||
item.ResetMarkStyle();
|
||
}
|
||
}
|
||
DocumentUtil.ClearProofreadMarks();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Log("ClearAllProofreadMark", ex);
|
||
}
|
||
try
|
||
{
|
||
// 清空marks
|
||
marks.Clear();
|
||
}
|
||
catch (Exception) { }
|
||
}
|
||
|
||
public void removeBookmark(string markId)
|
||
{
|
||
DocumentUtil.RemoveBookmark(markId);
|
||
}
|
||
//public void addBookmark(string data)
|
||
//{
|
||
// var item = JsonConvert.DeserializeObject<CorrectedContent>(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, int documentId)
|
||
{
|
||
var doc = documentId < 1 ? Globals.ThisAddIn.Application.ActiveDocument : GetDocumentById(documentId);
|
||
//
|
||
// 设置当前文档数据
|
||
Globals.ThisAddIn.ActiveCurrentDocumentMarks(doc);
|
||
|
||
if (proofreadId == selectProofreadId) return;
|
||
// 取消上一个标签移除
|
||
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);
|
||
}
|
||
}
|
||
|
||
private Document _currentDocument;
|
||
public Document CurrentDocument
|
||
{
|
||
get => _currentDocument ?? Globals.ThisAddIn.Application.ActiveDocument;
|
||
set
|
||
{
|
||
_currentDocument = value;
|
||
}
|
||
}
|
||
|
||
public string InitContent(string content, int documentId)
|
||
{
|
||
try
|
||
{
|
||
// 根据文档编号 获取当前文档避免数据混乱
|
||
CurrentDocument = GetDocumentById(documentId);
|
||
if (CurrentDocument == null)
|
||
{
|
||
throw new Exception("没有找到校对文档对象");
|
||
}
|
||
List<DocumentCorrectItem> list = JsonConvert.DeserializeObject<List<DocumentCorrectItem>>(content);
|
||
|
||
// 先清除所有数据
|
||
clearAllProofreadMark(CurrentDocument);
|
||
|
||
//var app = Globals.ThisAddIn.Application;
|
||
//var cur = app.Selection;
|
||
//
|
||
var prevOffset = 0;
|
||
List<int> disabledList = new List<int>();
|
||
foreach (var correct in list)
|
||
{
|
||
if (correct.Diffs != null && correct.Diffs.Count > 0)
|
||
{
|
||
prevOffset = 0;
|
||
int index = 0;
|
||
foreach (var item in correct.Diffs)
|
||
{
|
||
int _prev = prevOffset;
|
||
// 查找对应区域并再该区域添加书签
|
||
var mark = DocumentUtil.FindRangeAndCreateBookmark(item, correct, CurrentDocument, ref prevOffset);
|
||
// 防止调用方法中没有更新
|
||
if (_prev >= prevOffset)
|
||
{
|
||
prevOffset = correct.SentenceOffset + item.start;
|
||
}
|
||
|
||
if (item.tag != "i") index++;
|
||
if (mark != null)
|
||
{
|
||
marks.Add(item.id, new ProofreadItem(item, mark, documentId));
|
||
}
|
||
else
|
||
{
|
||
disabledList.Add(item.id);
|
||
var msg = new Dictionary<string, object>{
|
||
{"message","没有找到标记对象" },
|
||
{ "origin",item },
|
||
{ "origin_correct",correct },
|
||
{ "new_text",correct.NewText },
|
||
{ "paragraph_num",correct.ParagraphNumber },
|
||
};
|
||
Logger.Log(JsonConvert.SerializeObject(msg));
|
||
}
|
||
}
|
||
}
|
||
}
|
||
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)
|
||
{
|
||
try
|
||
{
|
||
var color = (WdColor)ColorTranslator.ToOle(Colors.FromHex(item.Value.content.color));
|
||
// 给选区添加背景颜色
|
||
item.Value.mark.Shading.BackgroundPatternColor = color;
|
||
}
|
||
catch (Exception)
|
||
{
|
||
//item.Value.mark.Shading.BackgroundPatternColor = WdColor.wdColorLightOrange;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// 隐藏面板对应校对项
|
||
MainPanelWebMessage.DisabledProofreadItem(disabledList);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Log("Initial Content error:" + ex.Message + "\n" + ex.StackTrace + "\n\n");
|
||
return "false";
|
||
}
|
||
return "true";
|
||
}
|
||
|
||
void SendMessageToPanel()
|
||
{
|
||
|
||
}
|
||
|
||
|
||
public string GetParagraph(int index)
|
||
{
|
||
try
|
||
{
|
||
var paragraphs = CurrentDocument.Paragraphs;
|
||
var total = paragraphs.Count;
|
||
// 判断索引是否超出范围
|
||
if (index > total)
|
||
{
|
||
return null;
|
||
}
|
||
var paragraph = CurrentDocument.Paragraphs[index];
|
||
return paragraph.Range.Text;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return "error:" + ex.Message;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新增校对项 查找时的偏移量
|
||
/// </summary>
|
||
private static readonly int INSERT_FIND_OFFSET = 5;
|
||
|
||
/// <summary>
|
||
/// 根据校对项查找文档对应的位置 并创建书签
|
||
/// </summary>
|
||
/// <param name="correct">校对项</param>
|
||
/// <param name="sentense">校对</param>
|
||
/// <param name="prevOffset"></param>
|
||
/// <returns></returns>
|
||
public Microsoft.Office.Tools.Word.Bookmark FindRangeAndCreateBookmark1(CorrectedContent correct, DocumentCorrectItem sentense, ref int prevOffset)
|
||
{
|
||
Microsoft.Office.Tools.Word.Bookmark bookmark = null;
|
||
try
|
||
{
|
||
var document = CurrentDocument;
|
||
ControlCollection controls = Globals.Factory.GetVstoObject(document).Controls;
|
||
var markName = Config.BuildBookmarkName(correct.id);
|
||
|
||
// 判断是否已经存在
|
||
if (controls.Contains(markName))
|
||
{
|
||
try
|
||
{
|
||
controls.Remove(markName);
|
||
}
|
||
catch (Exception) { }
|
||
}
|
||
Range findRange = null;
|
||
// 判断段落是否存在
|
||
if (sentense.ParagraphNumber > document.Paragraphs.Count) return null;
|
||
|
||
var paragraph = document.Paragraphs[sentense.ParagraphNumber];
|
||
Range paragraphRange = paragraph.Range;
|
||
var paragraphStart = paragraphRange.Start;
|
||
|
||
|
||
var Start = paragraphStart + sentense.SentenceOffset;
|
||
var End = Start + sentense.InsertLength - 1;
|
||
if (End > paragraphRange.End)
|
||
{
|
||
End = paragraphRange.End;
|
||
}
|
||
|
||
// 当前句子的选区
|
||
var fullRange = document.Range(Start, End);
|
||
// 如果选择有文本就用文本
|
||
string fullText = fullRange.Text ?? paragraphRange.Text;
|
||
// 当前段落文本
|
||
string paragraphText = paragraphRange.Text;
|
||
End = Start + correct.end;
|
||
Start = Start + correct.start;
|
||
// 避免越界
|
||
prevOffset = Math.Min(prevOffset, paragraphText.Length - 1);
|
||
|
||
int offset = sentense.SentenceOffset;
|
||
int length = sentense.InsertLength;
|
||
string originText = sentense.Insert;
|
||
|
||
// 如果是新增 则查找定位
|
||
if (correct.tag == "i")
|
||
{
|
||
// s1. 通过接口的位置 和 文档内容进行比对
|
||
try
|
||
{
|
||
// 判断接口的定位字符串和文档截取的字符串是否一致
|
||
if (paragraphText.Substring(offset, length) == originText)
|
||
{
|
||
// 直接使用接口定位
|
||
findRange = document.Range(Start, End);
|
||
}
|
||
}
|
||
catch (Exception exif)
|
||
{
|
||
Logger.Log(exif);
|
||
}
|
||
// s2. 位置不匹配 则采用搜索定位
|
||
if (findRange == null)
|
||
{
|
||
// 找前缀
|
||
var prefix = correct.start > 2 ? (
|
||
correct.start > INSERT_FIND_OFFSET
|
||
? originText.Substring(correct.start - INSERT_FIND_OFFSET, INSERT_FIND_OFFSET)
|
||
: originText.Substring(0, correct.start)
|
||
) : null;
|
||
// 找后缀
|
||
var suffix = prefix == null ? (
|
||
correct.end + INSERT_FIND_OFFSET < originText.Length
|
||
? originText.Substring(correct.start, INSERT_FIND_OFFSET)
|
||
: originText.Substring(correct.start, originText.Length - correct.start)
|
||
) : null;
|
||
// 偏移量
|
||
var start = prefix != null || suffix != null
|
||
? paragraphText.IndexOf(prefix ?? suffix, prevOffset)
|
||
: -1;
|
||
if (start != -1)
|
||
{
|
||
var findOffset = paragraphStart + start + (prefix != null ? prefix.Length : 0);
|
||
findRange = document.Range(findOffset, findOffset);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
findRange = document.Range(Start, End);
|
||
}
|
||
// 不是新增模式 且定位区域文本和原始文本不匹配
|
||
if (correct.tag != "i" && findRange.Text != correct.origin)
|
||
{
|
||
// 查找
|
||
findRange = DocumentUtil.FindRange(correct, sentense, ref prevOffset, CurrentDocument, paragraphRange);
|
||
}
|
||
|
||
// 能够找到对应的区域 则再对应区域添加书签
|
||
if (findRange != null)
|
||
{
|
||
// 更新查找的结束位置
|
||
prevOffset = findRange.End - paragraphStart;
|
||
bookmark = controls.AddBookmark(findRange, markName);
|
||
bookmark.Tag = "ai_proofread";
|
||
}
|
||
|
||
#region start
|
||
|
||
//// 判断并获取当前段落
|
||
|
||
|
||
//// 定位要操作的文字
|
||
//var r = document.Range(Start, End);
|
||
|
||
//// 判断选区是否正确
|
||
//if (item.tag == "i" || r.Text == item.origin)
|
||
//{
|
||
// bookmark = controls.AddBookmark(r, markName);
|
||
// bookmark.Tag = "ai_proofread";
|
||
//}
|
||
//else
|
||
//{
|
||
// object str = item.origin;
|
||
// FindRange(ref fullRange, ref str);
|
||
|
||
// if(fullRange != null){
|
||
// bookmark = controls.AddBookmark(fullRange, markName);
|
||
// bookmark.Tag = "ai_proofread";
|
||
// }
|
||
// //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);
|
||
// // if(r.Text == item.origin) { }
|
||
// // bookmark = controls.AddBookmark(r, markName);
|
||
// // bookmark.Tagetg = "ai_proofread";
|
||
// // break;
|
||
// // }
|
||
// // startPos = index;
|
||
// // findCount++;
|
||
// //}
|
||
//}
|
||
#endregion
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Logger.Log("create mark error:" + ex.Message + "\n" + ex.StackTrace + "\n\n");
|
||
}
|
||
return bookmark;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
///
|
||
/// </summary>
|
||
/// <param name="range"></param>
|
||
/// <param name="whatToFind"></param>
|
||
private void FindRange(ref Range range, ref object whatToFind)
|
||
{
|
||
object matchCase = false; // 是否区分大小写
|
||
object matchWholeWord = false; // 是否匹配整个单词
|
||
object matchWildcards = false; // 是否使用通配符
|
||
object forward = true; // 搜索方向,true表示向前搜索,false表示向后搜索
|
||
object wrap = Microsoft.Office.Interop.Word.WdFindWrap.wdFindContinue; // 搜索范围,这里表示继续搜索
|
||
|
||
range.Find.Execute(ref whatToFind, ref matchCase, ref matchWholeWord, ref matchWildcards, ref forward, ref wrap);
|
||
}
|
||
}
|
||
}
|