callmeyan 32e85c62c0 优化日志记录、资源管理及功能支持
- 引入 log4net 库,统一日志记录方式,提升可维护性。
- 优化异常处理,增加详细日志记录,增强代码健壮性。
- 调整资源文件引用,新增图标资源,删除无用资源。
- 优化文档事件处理逻辑,改进面板显示与隐藏逻辑。
- 增加对 WPS 环境的支持,动态调整功能行为。
- 禁用部分功能(如常识性检测、客服、升级和帮助)。
- 删除冗余代码,清理注释,统一代码风格。
- 更新程序集版本至 2.2.5,改进调试与生产环境配置。
2025-05-08 13:57:12 +08:00

1080 lines
38 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using AIProofread.Controls;
using AIProofread.core;
using AIProofread.Util;
using DocumentFormat.OpenXml.Office2013.WebExtentionPane;
using log4net;
using Microsoft.Office.Interop.Word;
using Newtonsoft.Json;
using UtilLib;
using CustomTaskPane = Microsoft.Office.Tools.CustomTaskPane;
namespace AIProofread.Model
{
/// <summary>
/// 文档信息 包含文档相关数据、面板及对文档的相关操作
/// </summary>
public class DocumentInfo
{
public ILog Logger = LogHelper.GetLogger(typeof(DocumentInfo));
public static readonly int MIN_WIDTH = 420;
private static char[] ArticleSpecialChars = new char[4] { '\a', '\r', '\v', '\f' };
private static object missing = System.Reflection.Missing.Value;
/// <summary>
/// 是否已经校对
/// </summary>
public bool hasProofreaded = false;
/// <summary>
/// 是否已经处理了校对结果
/// </summary>
public bool hasProcessMark = false;
/// <summary>
///
/// </summary>
public Dictionary<int, ProofreadItem> marks = new Dictionary<int, ProofreadItem>();
/// <summary>
/// 最小宽度
/// </summary>
public static int MinWidth = 0;
/// <summary>
/// 校对选区集合
/// </summary>
private List<Range> ranges = new List<Range>();
/// <summary>
/// 当前选中对现象编号
/// </summary>
private int selectProofreadId;
//private Document currentDocument;
/// <summary>
/// 当前对应文档
/// </summary>
public Document CurrentDocument { get; set; }
/// <summary>
/// 文件名称
/// </summary>
public string fileName;
private string uniqueId;
public string UniqueId { get { return uniqueId; } }
public string ProofreadCachePath
{
get
{
return CurrentDocument.FullName + "-proofread.json";
}
}
public bool IsActive { get; internal set; } = false;
public bool PaneVisible { get; set; } = false;
public int Id { get; set; }
public CustomTaskPane TaskPane { get; set; }
public WdProtectionType ProtectionType { get { return CurrentDocument.ProtectionType; } }
/// <summary>
/// 是否已校对
/// </summary>
public bool Proofread { get; set; }
/// <summary>
/// 是否校对中
/// </summary>
public bool Proofreading { get; set; }
// 初始化
public DocumentInfo(Document doc)
{
this.CurrentDocument = doc;
Initialize();
}
/// <summary>
/// 显示面板
/// </summary>
public void ShowPane()
{
if (null == TaskPane)
{
CreateTaskPane();
}
Logger.Debug("TaskPane.Visible {" + TaskPane == null ? "null" : (TaskPane.Visible ? "true" : "false") + " => true");
TaskPane.Visible = PaneVisible = true;
}
/// <summary>
/// 隐藏面板
/// </summary>
public void HidePane()
{
//if (!PaneVisible) return;
ShowDocumentStatus("HidePane");
Logger.Debug($"TaskPane.Visible {TaskPane.Visible} => false");
TaskPane.Visible = PaneVisible = false;
}
public void RunInMainThread(Action action)
{
Logger.Debug($"RunInMainThread {action}");
if (null == TaskPane)
{
CreateTaskPane();
}
TaskPane.Control.BeginInvoke(action);
}
public void ShowDialog(string message, string confirmText, string confirmAction)
{
TaskPane.Control.BeginInvoke(new Action(() =>
{
//MessageBox.Show(message, "提示");
FormMessage.ShowMessage(message, confirmText, confirmAction);
}));
}
public FormMessage ShowMessage(string message, int closeDelay, bool showCloseBtn = true)
{
var msgForm = FormMessage.ShowMessage(message, closeDelay);
if (closeDelay > 0)
{
if (!showCloseBtn)
{
msgForm.HideCloseBtn();
}
// n毫秒后自动关闭
System.Threading.Tasks.Task.Delay(closeDelay).ContinueWith(t =>
{
if (msgForm.IsDisposed) return;
TaskPane.Control.BeginInvoke(new Action(() =>
{
msgForm.Close();
}));
});
}
return msgForm;
}
public void ShowLogin(string action)
{
TaskPane.Control.BeginInvoke(new Action(() =>
{
FormLogin frm = new FormLogin(action);
Globals.ThisAddIn.LoginFormList.Add(frm);
frm.ShowDialog();
}));
}
private void ShowDocumentStatus(string tag)
{
// Logger.Log($"{fileName} {tag} PaneVisible is {PaneVisible} Poofread is {Proofread} Proofreading is {Proofreading}");
}
/// <summary>
/// 激活
/// </summary>
public void Active()
{
try
{
Logger.Debug("激活 for " + CurrentDocument.FullName + " 没有 visible is " + PaneVisible);
ShowDocumentStatus("Active");
IsActive = true;
if (Config.IS_WPS && null != TaskPane)
{
TaskPane.Visible = PaneVisible;
}
}
catch (Exception e)
{
Logger.Error("Active Error", e);
}
}
public void Deactive()
{
try
{
ShowDocumentStatus("Deactive");
IsActive = false;
if (Config.IS_WPS && null != TaskPane)
{
PaneVisible = TaskPane.Visible;
TaskPane.Visible = false;
Logger.Debug("取消 for " + CurrentDocument.FullName + " current visible " + PaneVisible);
}
}catch (Exception e)
{
Logger.Error("Deactive Error", e);
}
}
public void Dispose()
{
try
{
// 判断TaskPane是否已经释放
if (null == TaskPane) return;
if (TaskPane.Control.IsDisposed) return;
ProofreadMainControl control = (ProofreadMainControl)TaskPane.Control;
control.ResetWeb();
HidePane();
TaskPane?.Dispose();
// 释放com
try
{
Marshal.ReleaseComObject(CurrentDocument);
}
catch (Exception) { }
}
catch (Exception e)
{
LogHelper.Log("Error", e);
}
}
// 计算uniqueId
private void ComputeUniqueId()
{
string filename = CurrentDocument.FullName;
if (!string.IsNullOrEmpty(uniqueId) || string.IsNullOrEmpty(filename))
{
return;
}
// 通过文档路径生成唯一id
uniqueId = filename.GetHashCode().ToString();
}
/// <summary>
/// 添加变量控制重复调用
/// </summary>
private bool isResizing = false;
private void Control_SizeChanged(object sender, EventArgs e)
{
if (isResizing) return;
if (TaskPane != null && TaskPane.Visible && TaskPane.Width < MinWidth)
{
isResizing = true;
SendKeys.Send("{ESC}");
TaskPane.Width = MinWidth;
isResizing = false;
}
}
// 创建pane 并初始化
public void CreateTaskPane()
{
Logger.Debug("CreateTaskPane");
var control = new ProofreadMainControl();
if (MinWidth < 10)
{
MinWidth = MIN_WIDTH * control.LabelWidth() / 42;
}
// 创建pane
TaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(control, Config.RUN_IN_DEBUG ? CurrentDocument.Name : " ");
// 默认隐藏
TaskPane.Visible = false;
// 设置宽度
control.Width = MinWidth;
TaskPane.Width = MinWidth;
// 监听尺寸变化 防止最小尺寸小于设置值
control.SizeChanged += Control_SizeChanged;
TaskPane.VisibleChanged += TaskPane_VisibleChanged;
}
/// <summary>
/// 检查按钮状态
/// </summary>
public void CheckBtnStatus()
{
//
if (Globals.ThisAddIn.ribbon != null)
{
Globals.ThisAddIn.ribbon.BtnShowPanel.Enabled = !PaneVisible && Proofread;
Globals.ThisAddIn.ribbon.SetCommonBtnStatus(!Proofreading);
}
}
private void TaskPane_VisibleChanged(object sender, EventArgs e)
{
if (Config.IS_WPS)
{
if(CurrentDocument == Globals.ThisAddIn.ActiveDocument)
{
Logger.Debug($"VisibleChanged ${CurrentDocument.Name} is {TaskPane.Visible}");
// 如果已经隐藏 则记录隐藏用于(WPS)多面板的切换的处理
PaneVisible = TaskPane.Visible;
}
}
CheckBtnStatus();
//Globals.ThisAddIn.ribbon.BtnShowPanel.Enabled = !TaskPane.Visible && Proofread;
}
public void Initialize()
{
this.fileName = CurrentDocument.FullName;
ranges.Clear();
ComputeUniqueId();
if (TaskPane == null)
{
Logger.Debug("init document Initialize(318) and CreateTaskPane");
CreateTaskPane();
}
}
//处理文档选区时 判断当前选区是否有校对项 有则选择该范围
public void ProcessSelectionChange(Selection s)
{
// 判断选区内是否有书签
if (s.Bookmarks != null && s.Bookmarks.Count > 0)
{
// 判断是否时点击 点击的起始和结束位置相同
if (s.Range.Start == s.Range.End)
{
//
var count = s.Bookmarks.Count;
// 原则只有一个书签
//foreach (Microsoft.Office.Interop.Word.Bookmark item in s.Bookmarks)
//{
// int proofreadId = Config.GetBookmarkIdByName(item.Name);
// if (proofreadId > 0)
// {
// //Bridge.bridge.SelectMarkById(proofreadId, 0);
// return;
// }
//}
}
}
}
// 获取当前文档文本
public string GetAllText()
{
return CurrentDocument.Range().Text;
}
/// <summary>
/// 获取当前选中文本
/// </summary>
/// <returns></returns>
public string GetSelectedText()
{
// 获取当前文档的选区
var selection = Globals.ThisAddIn.Application.Selection;
return selection.Text;
}
/// <summary>
/// 获取指定选区的文本
/// </summary>
/// <param name="range"></param>
/// <returns></returns>
public string GetRangeText(Range range)
{
string text = range?.Text;
return string.IsNullOrEmpty(text) ? "" : text;
}
/// <summary>
/// 获取指定选区的文本
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
public string GetRangeText(int start, int end)
{
if (start >= end) return null;
return GetRangeText(CurrentDocument.Range(start, end));
}
public Range Range(int start, int end)
{
if (start >= end) return null;
return CurrentDocument.Range(start, end);
}
/// <summary>
/// 保存校对缓存结果
/// </summary>
private void SaveProofreadCache(string cacheData)
{
// 判断文档是否已经保存
if (!CurrentDocument.Saved)
{
// 保存文档
if (!CurrentDocument.Saved)
{
// 提示保存文档
var result = MessageBox.Show("当前文档尚未保存,是否保存?", "提示", MessageBoxButtons.YesNo);
if (result == DialogResult.Yes)
{
CurrentDocument.Save();
}
else
{
return;
}
}
}
}
// 定位所有的校对项
public void LocateAllProofreadItems(List<CorrectContext> list)
{
// 获取所有的校对项
//List<Range> proofreadItems = GetProofreadItems();
var prevOffset = 0;
foreach (var item in list)
{
if (item.CorrectItems != null && item.CorrectItems.Count > 0)
{
foreach (var correct in item.CorrectItems)
{
var range = LocateProofreadItem(correct, item, ref prevOffset);
if (range == null) continue;
}
}
}
}
/// <summary>
/// 查找偏移量
/// </summary>
private static readonly int INSERT_FIND_OFFSET = 5;
/// <summary>
/// 定位校对项
/// </summary>
/// <param name="correct">校对项</param>
/// <param name="ctx">校对上下文</param>
/// <param name="prevOffset">上一步的</param>
/// <returns></returns>
private Range LocateProofreadItem(CorrectItem correct, CorrectContext ctx, ref int prevOffset)
{
var document = CurrentDocument;
// 校对项的段落号超过文档的段落数,直接返回
if (ctx.ParagraphNumber > document.Paragraphs.Count) return null;
// 获取当前段落
var paragraph = document.Paragraphs[ctx.ParagraphNumber];
if (paragraph == null) return null;
var paraRange = paragraph.Range;
var paraText = paraRange.Text;
var paraStart = paraRange.Start;
//var offset = paraStart + ctx.SentenceOffset;
//var cutLength = Math.Min(c.InsertLen, paraText.Length - offset);
var sentence = paraRange.Sentences[ctx.SentenceNumber]; //paraText.Substring(ctx.SentenceOffset, ctx.InsertLength);
ctx.SentenceOffset = sentence.Start;
var offset = paraStart + ctx.SentenceOffset;
if (sentence.Text == ctx.Insert)
{ // 比对原始内容与校对原文是否一致
var range = document.Range(offset + correct.Start, offset + correct.End);
//
if (range.Text == correct.Origin) return range;
}
var originText = ctx.Insert;
// 如果是新增 则查找定位
if (correct.Tag == "i")
{
// 找前缀
var prefix1 = 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 suffix1 = prefix1 == 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 start1 = prefix1 != null || suffix1 != null
? paraText.IndexOf(prefix1 ?? suffix1, prevOffset)
: -1;
if (start1 != -1)
{
var findOffset = paraStart + start1 + (prefix1 != null ? prefix1.Length : 0);
return document.Range(findOffset, findOffset);
}
}
// 执行查找
int wordStart = correct.Start;
int wordEnd = correct.End;
// 找前缀
var prefix = wordStart > 2 ? (
wordStart > INSERT_FIND_OFFSET
? originText.Substring(wordStart - INSERT_FIND_OFFSET, INSERT_FIND_OFFSET)
: originText.Substring(0, wordStart)
) : null;
// 找后缀
var suffix = prefix == null ? (
wordEnd + INSERT_FIND_OFFSET < originText.Length
? originText.Substring(wordStart, INSERT_FIND_OFFSET)
: originText.Substring(wordStart, originText.Length - wordStart)
) : null;
var start = prefix != null || suffix != null
? paraText.IndexOf(prefix ?? suffix, prevOffset) // item.start +
: -1;
if (start != -1)
{
var findOffset = paraRange.Start + start + (prefix != null ? prefix.Length : 0);
var range = document.Range(findOffset, findOffset + wordEnd - wordStart);
if (range.Text == correct.Origin) { return range; }
}
// 直接定位查找
start = paraText.IndexOf(correct.Origin, prevOffset);
if (start == -1) return null;
// 定位整体开始位置
start = paraStart + start;
return document.Range(start, start + correct.Origin.Length);
}
public void GlobalCallback(string callbackId, string result)
{
ProofreadMainControl control = (ProofreadMainControl)TaskPane.Control;
try
{
if (control.web.CoreWebView2 == null)
{
Thread.Sleep(1000);
}
control.web.CoreWebView2.ExecuteScriptAsync($"window.__global_callback_function('{callbackId}','{result}');");
}
catch (Exception ex)
{
LogHelper.Log("GlobalCallback", "call web global function error \n" + ex.Message + "\n" + callbackId + result);
}
}
public void SendMessageToWeb(string msg, object data)
{
var json = JsonConvert.SerializeObject(new WebMessage(msg, data));
ProofreadMainControl control = (ProofreadMainControl)TaskPane.Control;
try
{
if (control.web.CoreWebView2 == null)
{
Thread.Sleep(1000);
}
control.web.CoreWebView2.PostWebMessageAsJson(json);
}
catch (Exception ex)
{
LogHelper.Log("SendMessage", "send message to web error \n" + ex.Message + "\n" + msg + data.ToString());
}
}
public void ClearAllProofreadMark()
{
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)
{
LogHelper.Log("ClearAllProofreadMark", ex);
}
// 清空marks
marks.Clear();
}
public void SelectMarkById(int proofreadId)
{
SelectMarkById(proofreadId, true);
}
/// <summary>
/// 选中标签
/// </summary>
/// <param name="proofreadId"></param>
public void SelectMarkById(int proofreadId, bool noticeToWeb)
{
if (proofreadId == selectProofreadId) return;
// 取消上一个标签移除
if (selectProofreadId != -1 && marks.ContainsKey(selectProofreadId))
{
var m = marks[selectProofreadId];
if (m != null && CurrentDocument.Bookmarks.Exists(m.Name))
{
marks[selectProofreadId].UnSelect();
}
else
{
marks.Remove(selectProofreadId);
}
}
selectProofreadId = proofreadId;
if (proofreadId != -1 && marks.ContainsKey(proofreadId))
{
var mark = marks[proofreadId].mark;
if (mark == null) return;
// 已经不存在该标签了
if (mark != null && !CurrentDocument.Bookmarks.Exists(mark.Name))
{
marks.Remove(proofreadId);
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;
var targetRange = mark.Range;
// 选中
targetRange.Select();
Globals.ThisAddIn.Application.ActiveWindow.ScrollIntoView(targetRange);//.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);
}
if (noticeToWeb)
{
Globals.ThisAddIn.SendMessageToWeb("select-proofread", proofreadId);
}
}
public void InitProofread(List<CorrectContext> list)
{
hasProofreaded = true;
int prevOffset = 0;
List<int> disabledList = new List<int>();
List<InsertMarkData> insertMarks = new List<InsertMarkData>();
foreach (var correct in list)
{
if (LogHelper.LoggerForm != null)
{
LogHelper.Log(string.Format("correct content:{0}", correct.Insert));
}
int currentOffset = correct.SentenceOffset;
if (correct.CorrectItems != null && correct.CorrectItems.Count > 0)
{
prevOffset = 0;
int index = 0;
foreach (var item in correct.CorrectItems)
{
if (marks.ContainsKey(item.Id)) continue;
// Logger.Log(string.Format("mark type {0} data {1}->{2}", item.Tag, item.Origin, item.Text));
int _prev = prevOffset;
bool isDisabled = false;
// 判断查找内容是否在原始数据中,否则直跳过
if (item.Tag != "i" && item.Origin.Trim().Length > 0)
{
isDisabled = correct.Insert.IndexOf(item.Origin) == -1;
}
// 查找对应区域并再该区域添加书签
var mark = isDisabled ? null : DocumentUtil.FindRangeAndCreateBookmark(item, correct, CurrentDocument, ref prevOffset);
// 防止调用方法中没有更新
if (_prev >= prevOffset)
{
prevOffset = currentOffset + item.Start;
}
if (item.Tag != "i") index++;
if (mark != null)
{
marks.Add(item.Id, new ProofreadItem(item, correct.Insert, mark, Id));
try
{
if (item.Tag == "i")
{
insertMarks.Add(new InsertMarkData()
{
Mark = mark,
InsertLength = item.Text.Length
});
}
else
{
SetMarkStyle(mark);
}
}
catch (Exception e)
{
LogHelper.Log(string.Format("mark color error {0}", e.Message));
}
}
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 },
};
LogHelper.Log(JsonConvert.SerializeObject(msg));
}
}
}
}
// 为了避免影响其他文本定位,操作完成后才使用空格填充
try
{
foreach (var item in insertMarks)
{
item.Mark.Text = ToolUtil.GetBlankText(item.InsertLength);
SetMarkStyle(item.Mark);
}
}
catch (Exception) { }
insertMarks.Clear();
//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);
}
private void SetMarkStyle(Microsoft.Office.Tools.Word.Bookmark mark)
{
// 颜色转码
var color = (WdColor)ColorTranslator.ToOle(Colors.FromHex(Config.TextBackgroundColor));
// 给选区添加背景颜色
mark.Shading.BackgroundPatternColor = color;
}
public void InitProofreadCache(List<CorrectContext> list, Dictionary<int, ProofreadRangeInfo> itemInfoDic)
{
marks.Clear();
foreach (var correct in list)
{
correct.CorrectItems.ForEach(item =>
{
var mark = DocumentUtil.FindBookMarkByCorrect(item);
if (mark != null)
{
var pi = new ProofreadItem(item, correct.Insert, mark, Id);
// 是否存在样式信息
if (itemInfoDic != null && itemInfoDic.ContainsKey(item.Id))
{
// 获取样式信息并还原
var info = itemInfoDic[item.Id];
try
{
pi.originColor = info.Color;
pi.originBackgroundColor = info.Background;
pi.originSize = info.Size;
}
catch (Exception ex) { LogHelper.Log(ex); }
}
marks.Add(item.Id, pi);
}
});
//marks.Add(item.Id, new ProofreadItem(item.CorrectItems[0], null, Id));
}
}
private void FindMarkByCorrectItem()
{
}
public DocumentContent GetAllParagraphs()
{
string rangeText = CurrentDocument.Content.Text;
string 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 = CurrentDocument.Paragraphs;
int total = paragraphs.Count;
for (int i = 1; i <= total; i++)
{
list.Add(GetParagraphText(paragraphs[i]));
}
return new DocumentContent()
{
OriginCut = array4,
TrimCut = array5,
Paragraphs = list.ToArray(),
};
}
private string GetParagraphText(Paragraph paragraph)
{
// 需要
return GetRangeText(paragraph.Range);
}
/// <summary>
/// 获取文档段落总数
/// </summary>
/// <returns></returns>
public int GetTotalParagraphNumber()
{
return CurrentDocument.Paragraphs.Count;
}
/// <summary>
/// 读取文档原始文件并转换成base64
/// </summary>
/// <returns></returns>
public string GetOriginFileData()
{
FileStream fs = new FileStream(CurrentDocument.FullName, FileMode.Open, FileAccess.Read, FileShare.Read);
byte[] bytes = new byte[fs.Length];
fs.Read(bytes, 0, bytes.Length);
return Convert.ToBase64String(bytes);
}
/// <summary>
/// 采纳校对项
/// </summary>
/// <param name="proofreadId"></param>
/// <param name="status"></param>
internal void ProcessMark(int proofreadId, int status)
{
// 是否存在书签
if (proofreadId > 0 && marks.ContainsKey(proofreadId))
{
hasProcessMark = true;
// 采纳
marks[proofreadId].Process(status);
}
else
{
Logger.Debug("不存在此校对项");
}
}
internal bool Saved()
{
if (CurrentDocument.Saved)
{
return true;
}
if (!hasProofreaded && !CurrentDocument.Saved) // 没有校对前需要提示保存
{
return false;
}
if (hasProofreaded && hasProcessMark && !CurrentDocument.Saved)
{
return false;
}
return true;
}
public void Save()
{
try
{
CurrentDocument.Save();
}
catch (Exception ex)
{
LogHelper.Log(ex);
}
}
public void FocusToPanel()
{
TaskPane.Visible = true;
TaskPane.Control.Focus();
}
public void Close()
{
try
{
// 清除标记内存数据
marks.Clear();
// 清除区域相关数据
ranges.Clear();
// TaskPane.Dispose();
this.Dispose();
}
catch (Exception ex)
{
LogHelper.Log(ex);
}
}
public void ExportResult(string modelType)
{
TaskPane.Control.BeginInvoke(new Action(() =>
{
DocumentUtil.ExportProofreadResult(modelType);
}));
}
public void ShowUpgrade(string data, bool force)
{
TaskPane.Control.BeginInvoke(new Action(() =>
{
var upgradeData = JsonConvert.DeserializeObject<UpgradeData>(data);
var needUpgrade = upgradeData.NeedUpgrade(Config.APP_VERSION);
//force = force && !Config.UpgradeForcedNotice;
if (force)
{
// 已经强制更新但被忽略过则不再提示
if (Config.UpgradeForcedNotice) return;
var result = MessageBox.Show(upgradeData.Message, "是否确认更新", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question);
if (result == DialogResult.No)
{
Config.UpgradeForcedNotice = true;
Globals.ThisAddIn.ribbon.SetBtnStatus("disable-by-upgrade", false);
return;
}
}
if (upgradeData.Ext == 1)
{
if (!needUpgrade)
{
ShowDialog("当前版本为最新版本,无需升级", "", "");
}
else
{
if (!force)
{
// 非强制则再问一次
var ret = MessageBox.Show(upgradeData.Message, "是否确认更新", System.Windows.Forms.MessageBoxButtons.YesNo, System.Windows.Forms.MessageBoxIcon.Question);
if (ret == DialogResult.No)
{
Globals.ThisAddIn.ribbon.SetBtnStatus("disable-by-upgrade", false);
return;
}
}
Bridge.bridge.OpenUrlWithOsBrowser(upgradeData.DownloadUrl);
}
}
else
{
Bridge.StartUpgradeProcess();
}
}));
}
public void ShowSetting()
{
TaskPane.Control.BeginInvoke(new Action(() =>
{
FormSetting frm = new FormSetting();
frm.Show();
}));
}
public void ShowWebView(string url, int width, int height, bool dialog)
{
TaskPane.Control.BeginInvoke(new Action(() =>
{
FormWebView view = new FormWebView(url, width, height);
if (dialog)
{
view.StartPosition = FormStartPosition.CenterScreen;
view.ShowDialog();
}
else
{
view.StartPosition = FormStartPosition.CenterParent;
view.Show();
}
}));
}
public Dictionary<int, ProofreadRangeInfo> GetProofreadOriginData()
{
Dictionary<int, ProofreadRangeInfo> dic = new Dictionary<int, ProofreadRangeInfo>();
// 变量文档所有marks 记录mark对应range的背景、大小、颜色
foreach (var item in marks)
{
if (item.Value.mark != null)
{
// 添加到数据
dic.Add(item.Key, new ProofreadRangeInfo()
{
Background = item.Value.originBackgroundColor,
Color = item.Value.originColor,
Size = item.Value.originSize
});
}
}
return dic;
}
public void CheckPanel()
{
LogHelper.Log(CurrentDocument.FullName + $" TaskPane visible {PaneVisible} has " + (TaskPane == null ? "null" : "exists"));
if (TaskPane == null) CreateTaskPane();
}
}
}