diff --git a/.vs/AIProofread/v17/.suo b/.vs/AIProofread/v17/.suo index b1815a6..13c10d2 100644 Binary files a/.vs/AIProofread/v17/.suo and b/.vs/AIProofread/v17/.suo differ diff --git a/AIProofread/Bridge.cs b/AIProofread/Bridge.cs index bfaa45b..42ac404 100644 --- a/AIProofread/Bridge.cs +++ b/AIProofread/Bridge.cs @@ -7,6 +7,7 @@ using Microsoft.Office.Tools.Word; using Microsoft.Web.WebView2.Core; using Microsoft.Web.WebView2.WinForms; using Newtonsoft.Json; +using NPOI.XSSF.UserModel; using NPOI.XWPF.UserModel; using System; using System.Collections.Generic; @@ -259,11 +260,14 @@ namespace AIProofread { Dictionary data = new Dictionary(); - var doc = Globals.ThisAddIn.Application.ActiveDocument; - string ext = doc.FullName.ToLower(); + var documentInfo = Globals.ThisAddIn.ActiveDocument; + + var doc = documentInfo.CurrentDocument; + //string ext = doc.FullName.ToLower(); // 如果是 - var shouldCheckSaved = ext.EndsWith(".wps") || doc.Paragraphs.Count < 200 || doc.Tables.Count < 20; - if (!shouldCheckSaved && !doc.Saved) + //var shouldCheckSaved = ext.EndsWith(".wps") || doc.Paragraphs.Count < 200 || doc.Tables.Count < 20; + // !shouldCheckSaved && + if (!documentInfo.Saved()) { data.Add("code", 1); data.Add("message", "请保存文档后再进行校对"); @@ -280,7 +284,7 @@ namespace AIProofread } else { - + documentInfo.hasProcessMark = false; data.Add("code", 0); data.Add("message", "success"); data.Add("name", doc.Name); @@ -536,7 +540,7 @@ namespace AIProofread public void SelectMarkById(int proofreadId, int documentId) { - Globals.ThisAddIn.ActiveDocument?.SelectMarkById(proofreadId); + Globals.ThisAddIn.ActiveDocument?.SelectMarkById(proofreadId,false); } public void processMark(int proofreadId, int status) @@ -572,7 +576,6 @@ namespace AIProofread /// //private static readonly int INSERT_FIND_OFFSET = 5; - public string MarkSentence(string content, int documentId) { // 初始化话 @@ -603,6 +606,19 @@ namespace AIProofread } } + public string ExportProofreadResult() + { + try + { + DocumentUtil.ExportProofreadResult(); + return BridgeResult.Success(); + } + catch (Exception ex) + { + return BridgeResult.Error(-1, ex.Message); + } + } + public string ReadText(string path) { try diff --git a/AIProofread/Controls/FormMessage.cs b/AIProofread/Controls/FormMessage.cs index d3dabd8..4e9bc0f 100644 --- a/AIProofread/Controls/FormMessage.cs +++ b/AIProofread/Controls/FormMessage.cs @@ -1,11 +1,4 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace AIProofread.Controls diff --git a/AIProofread/Model/DocumentInfo.cs b/AIProofread/Model/DocumentInfo.cs index fe245df..92598d8 100644 --- a/AIProofread/Model/DocumentInfo.cs +++ b/AIProofread/Model/DocumentInfo.cs @@ -23,6 +23,14 @@ namespace AIProofread.Model private static char[] ArticleSpecialChars = new char[4] { '\a', '\r', '\v', '\f' }; private static object missing = System.Reflection.Missing.Value; + /// + /// 是否已经校对 + /// + public bool hasProofreaded = false; + /// + /// 是否已经处理了校对结果 + /// + public bool hasProcessMark = false; /// /// @@ -70,6 +78,7 @@ namespace AIProofread.Model public int Id { get; set; } public CustomTaskPane TaskPane { get; set; } + public WdProtectionType ProtectionType { get { return CurrentDocument.ProtectionType; } } // 初始化 public DocumentInfo(Document doc) @@ -443,15 +452,20 @@ namespace AIProofread.Model marks.Clear(); } + + public void SelectMarkById(int proofreadId) + { + SelectMarkById(proofreadId, true); + } /// /// 选中标签 /// /// - public void SelectMarkById(int proofreadId) + public void SelectMarkById(int proofreadId, bool noticeToWeb) { if (proofreadId == selectProofreadId) return; // 取消上一个标签移除 - if (selectProofreadId > 0 && marks.ContainsKey(selectProofreadId)) + if (proofreadId != -1 && marks.ContainsKey(selectProofreadId)) { var m = marks[selectProofreadId]; if (m != null && CurrentDocument.Bookmarks.Exists(m.Name)) @@ -465,7 +479,7 @@ namespace AIProofread.Model } selectProofreadId = proofreadId; - if (proofreadId > 0 && marks.ContainsKey(proofreadId)) + if (proofreadId != -1 && marks.ContainsKey(proofreadId)) { var mark = marks[proofreadId].mark; if (mark == null) return; @@ -492,12 +506,16 @@ namespace AIProofread.Model marks[proofreadId].Select(); //Globals.ThisAddIn.SendMessageToWeb("select", proofreadId); } - Globals.ThisAddIn.SendMessageToWeb("select-proofread", proofreadId); + if (noticeToWeb) + { + Globals.ThisAddIn.SendMessageToWeb("select-proofread", proofreadId); + } } public void InitProofread(List list) { + hasProofreaded = true; int prevOffset = 0; List disabledList = new List(); @@ -510,6 +528,7 @@ namespace AIProofread.Model 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; // 查找对应区域并再该区域添加书签 @@ -524,6 +543,31 @@ namespace AIProofread.Model if (mark != null) { marks.Add(item.Id, new ProofreadItem(item,correct.Insert, mark, Id)); + try + { + if (item.Tag == "i") + { // 使用空格填充 + mark.Text = ToolUtil.GetBlankText(item.Text.Length); + } + if (item.Color != null) + { + + // 颜色转码 + var color = (WdColor)ColorTranslator.ToOle(Colors.FromHex(item.Color)); + // 给选区添加背景颜色 + mark.Shading.BackgroundPatternColor = color; + //try + //{ + //} + //catch (Exception) + //{ + // //item.Value.mark.Shading.BackgroundPatternColor = WdColor.wdColorLightOrange; + //} + } + }catch(Exception e) + { + Logger.Log(string.Format("mark color error {0}",e.Message)); + } } else { @@ -540,29 +584,29 @@ namespace AIProofread.Model } } } - 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; - } - } - } - } + //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); @@ -646,8 +690,26 @@ namespace AIProofread.Model { if (proofreadId > 0 && marks.ContainsKey(proofreadId)) { + hasProcessMark = true; marks[proofreadId].Process(status); + } + } + + internal bool Saved() + { + if (CurrentDocument.Saved) + { + return true; } + if(!hasProofreaded && !CurrentDocument.Saved) // 没有校对前需要提示保存 + { + return false; + } + if(hasProofreaded && hasProcessMark && !CurrentDocument.Saved) + { + return false; + } + return true; } } } diff --git a/AIProofread/Ribbon1.cs b/AIProofread/Ribbon1.cs index 080af1b..9535327 100644 --- a/AIProofread/Ribbon1.cs +++ b/AIProofread/Ribbon1.cs @@ -3,21 +3,13 @@ using System; using System.Diagnostics; using AIProofread.Controls; using UtilLib; -using System.Drawing; -using System.Security.Cryptography; using Microsoft.Office.Interop.Word; -using System.IO; -using System.Threading.Tasks; using AIProofread.Util; -using Microsoft.Office.Tools.Word; using System.Collections.Generic; using System.Linq; using System.Text; using AIProofread.core; using System.Windows.Forms; -using NPOI.XSSF.UserModel; -using NPOI.SS.UserModel; -using AIProofread.Model; namespace AIProofread { @@ -473,130 +465,11 @@ namespace AIProofread Process.Start(AppDomain.CurrentDomain.BaseDirectory); } - private ICellStyle CreateBaseCellStyle(IWorkbook workbook) - { - var style = workbook.CreateCellStyle(); - style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; - style.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center; - style.WrapText = true; - - return style; - } - private IFont CreateBaseFont(IWorkbook workbook) - { - // 宋体 11 - var font = workbook.CreateFont(); - font.FontName = "宋体"; - font.FontHeightInPoints = 11; - - return font; - } private void BtnExportProofreadResult_Click(object sender, RibbonControlEventArgs e) { - SaveFileDialog sfd = new SaveFileDialog(); - sfd.Filter = "Excel文件|*.xlsx"; - var result = sfd.ShowDialog(); - // 如果用户取消选择,则返回 - if(result == DialogResult.Cancel) - { - return; - } - using (var fs = File.OpenWrite(sfd.FileName)) - { - var book = new XSSFWorkbook(); - var sheet = book.CreateSheet("Sheet1"); - // 设置表格样式 - var style = CreateBaseCellStyle(book); - style.SetFont(CreateBaseFont(book)); - style.BorderBottom = NPOI.SS.UserModel.BorderStyle.None; - style.BorderTop = NPOI.SS.UserModel.BorderStyle.None; - style.BorderLeft = NPOI.SS.UserModel.BorderStyle.None; - style.BorderRight = NPOI.SS.UserModel.BorderStyle.None; - style.WrapText = true; - sheet.SetDefaultColumnStyle(0, style); - sheet.SetDefaultColumnStyle(1, style); - sheet.SetDefaultColumnStyle(2, style); - sheet.SetDefaultColumnStyle(3, style); - sheet.SetDefaultColumnStyle(4, style); - sheet.SetDefaultColumnStyle(5, style); - sheet.SetDefaultColumnStyle(6, style); - - - // 表头设置 - var row = sheet.CreateRow(0); - row.CreateCell(0).SetCellValue("序号"); - row.CreateCell(1).SetCellValue("页"); - row.CreateCell(2).SetCellValue("行"); - - var cell = row.CreateCell(3);// - // 设置宽度 - sheet.SetColumnWidth(3, 50 * 256); - cell.SetCellValue("详细信息"); - - var cellExp = row.CreateCell(4); - // 设置文字颜色为红色 - var expStyle = book.CreateCellStyle(); - var f1 = CreateBaseFont(book); - f1.Color = NPOI.HSSF.Util.HSSFColor.Red.Index; - expStyle.SetFont(f1); - cellExp.CellStyle = expStyle; - cellExp.SetCellValue("异常"); - - var suggestCell = row.CreateCell(5);// - suggestCell.CellStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index; - suggestCell.SetCellValue("建议"); - - row.CreateCell(6).SetCellValue("处理状态"); - - var blackFont = CreateBaseFont(book); - blackFont.Color = NPOI.HSSF.Util.HSSFColor.Black.Index; - var redFont = CreateBaseFont(book); - redFont.Color = NPOI.HSSF.Util.HSSFColor.Red.Index; - - int id = 1; - foreach (var item in Globals.ThisAddIn.ActiveDocument.marks) - { - if(item.Value.mark == null) continue; - var it = item.Value.content; - var range = item.Value.mark.Range; - - // 获取书签在文档的页码数 - var pageNumber = range.get_Information(WdInformation.wdActiveEndPageNumber); - // 获取书签在当前页面的行数 - var lineNumber = range.get_Information(WdInformation.wdFirstCharacterLineNumber); - row = sheet.CreateRow(id); - row.CreateCell(0).SetCellValue(id); - row.CreateCell(1).SetCellValue(pageNumber); - row.CreateCell(2).SetCellValue(lineNumber); - - XSSFRichTextString originText = new XSSFRichTextString(item.Value.OriginSentence); - originText.ApplyFont(blackFont); - var startIndex = item.Value.OriginSentence.IndexOf(it.Origin); - // 对查找内容引用红色 - originText.ApplyFont(startIndex, startIndex + it.Origin.Length, redFont); - row.CreateCell(3).SetCellValue(originText); - - row.CreateCell(4).SetCellValue(it.Origin); - row.CreateCell(5).SetCellValue(it.Text); - row.CreateCell(6).SetCellValue(StatusText(it.IsAccept)); - id++; - } - - // 保存到文件 - book.Write(fs); - MessageBox.Show("导出成功"); - } - } - - private string StatusText(int status) - { - if(status == AcceptStatus.Accept) return "采纳"; - else if (status == AcceptStatus.Review) return "采纳"; - else if (status == AcceptStatus.Ignore) return "忽略"; - - return "未处理"; + Globals.ThisAddIn.SendMessageToWeb("export-result", ""); } } } diff --git a/AIProofread/ThisAddIn.cs b/AIProofread/ThisAddIn.cs index fcd6220..6812fd6 100644 --- a/AIProofread/ThisAddIn.cs +++ b/AIProofread/ThisAddIn.cs @@ -8,6 +8,7 @@ using AIProofread.Controls; using UtilLib; using AIProofread.Model; using System.Collections.Generic; +using System.Runtime.InteropServices; //using CustomTaskPane = Microsoft.Office.Core.CustomTaskPane; //using CustomTaskPane = Microsoft.Office.Tools.CustomTaskPane; //using NPOI.SS.Formula.Functions; @@ -311,7 +312,8 @@ namespace AIProofread { // 只选择第一个书签 // TODO: 优化 - Bridge.bridge.SelectMarkById(proofreadId, 0); + //Bridge.bridge.SelectMarkById(proofreadId, 0); + ActiveDocument?.SelectMarkById(proofreadId, true); return; } } @@ -351,14 +353,20 @@ namespace AIProofread this.documentList.HideAllPane(); } + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool SetForegroundWindow(IntPtr hWnd); + /// /// 显示登录窗口 /// /// - public void ShowLoginForm(string action) - { + public void ShowLoginForm(string action) { + // 关闭之前的窗口 + if(LoginFormList.Count > 0){ + LoginFormList.ForEach(f => f.Close()); + } FormLogin frm = new FormLogin(action); - LoginFormList.Add(frm); frm.Show(); } diff --git a/AIProofread/core/DocumentUtil.cs b/AIProofread/core/DocumentUtil.cs index 79f76ff..9299125 100644 --- a/AIProofread/core/DocumentUtil.cs +++ b/AIProofread/core/DocumentUtil.cs @@ -9,6 +9,10 @@ using Microsoft.Office.Tools.Word; using Bookmark = Microsoft.Office.Tools.Word.Bookmark; using Section = Microsoft.Office.Interop.Word.Section; using WdColor = Microsoft.Office.Interop.Word.WdColor; +using NPOI.XSSF.UserModel; +using System.Windows.Forms; +using NPOI.SS.UserModel; +using System.IO; namespace AIProofread { @@ -379,7 +383,7 @@ namespace AIProofread if (sentence.Text == c.Insert) { // 比对原始内容与校对原文是否一致 - var range = document.Range(offset + item.Start, offset + item.End); + var range = document.Range(offset + item.Start, offset + item.End + 1); // if (range.Text == item.Origin) return range; } @@ -407,7 +411,7 @@ namespace AIProofread if (start1 != -1) { var findOffset = paraStart + start1 + (prefix1 != null ? prefix1.Length : 0); - return document.Range(findOffset, findOffset); + return document.Range(findOffset, findOffset + 1); } } @@ -434,7 +438,7 @@ namespace AIProofread if (start != -1) { var findOffset = paraRange.Start + start + (prefix != null ? prefix.Length : 0); - var range = document.Range(findOffset, findOffset + wordEnd - wordStart); + var range = document.Range(findOffset, findOffset + wordEnd - wordStart + 1); if (range.Text == item.Origin) { return range; } } // 直接定位查找 @@ -445,5 +449,130 @@ namespace AIProofread return document.Range(start, start + item.Origin.Length); } + + public static void ExportProofreadResult() + { + SaveFileDialog sfd = new SaveFileDialog(); + sfd.Filter = "Excel文件|*.xlsx"; + var result = sfd.ShowDialog(); + // 如果用户取消选择,则返回 + if (result == DialogResult.Cancel) + { + return; + } + using (var fs = File.OpenWrite(sfd.FileName)) + { + var book = new XSSFWorkbook(); + var sheet = book.CreateSheet("Sheet1"); + // 设置表格样式 + var style = CreateBaseCellStyle(book); + style.SetFont(CreateBaseFont(book)); + style.BorderBottom = NPOI.SS.UserModel.BorderStyle.None; + style.BorderTop = NPOI.SS.UserModel.BorderStyle.None; + style.BorderLeft = NPOI.SS.UserModel.BorderStyle.None; + style.BorderRight = NPOI.SS.UserModel.BorderStyle.None; + style.WrapText = true; + sheet.SetDefaultColumnStyle(0, style); + sheet.SetDefaultColumnStyle(1, style); + sheet.SetDefaultColumnStyle(2, style); + sheet.SetDefaultColumnStyle(3, style); + sheet.SetDefaultColumnStyle(4, style); + sheet.SetDefaultColumnStyle(5, style); + sheet.SetDefaultColumnStyle(6, style); + + + // 表头设置 + var row = sheet.CreateRow(0); + row.CreateCell(0).SetCellValue("序号"); + row.CreateCell(1).SetCellValue("页"); + row.CreateCell(2).SetCellValue("行"); + + var cell = row.CreateCell(3);// + // 设置宽度 + sheet.SetColumnWidth(3, 50 * 256); + cell.SetCellValue("详细信息"); + + var cellExp = row.CreateCell(4); + // 设置文字颜色为红色 + var expStyle = book.CreateCellStyle(); + var f1 = CreateBaseFont(book); + f1.Color = NPOI.HSSF.Util.HSSFColor.Red.Index; + expStyle.SetFont(f1); + cellExp.CellStyle = expStyle; + cellExp.SetCellValue("异常"); + + var suggestCell = row.CreateCell(5);// + suggestCell.CellStyle.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index; + suggestCell.SetCellValue("建议"); + + row.CreateCell(6).SetCellValue("处理状态"); + + var blackFont = CreateBaseFont(book); + blackFont.Color = NPOI.HSSF.Util.HSSFColor.Black.Index; + var redFont = CreateBaseFont(book); + redFont.Color = NPOI.HSSF.Util.HSSFColor.Red.Index; + + int id = 1; + foreach (var item in Globals.ThisAddIn.ActiveDocument.marks) + { + if (item.Value.mark == null) continue; + var it = item.Value.content; + var range = item.Value.mark.Range; + + // 获取书签在文档的页码数 + var pageNumber = range.get_Information(WdInformation.wdActiveEndPageNumber); + // 获取书签在当前页面的行数 + var lineNumber = range.get_Information(WdInformation.wdFirstCharacterLineNumber); + row = sheet.CreateRow(id); + row.CreateCell(0).SetCellValue(id); + row.CreateCell(1).SetCellValue(pageNumber); + row.CreateCell(2).SetCellValue(lineNumber); + + XSSFRichTextString originText = new XSSFRichTextString(item.Value.OriginSentence); + originText.ApplyFont(blackFont); + var startIndex = item.Value.OriginSentence.IndexOf(it.Origin); + // 对查找内容引用红色 + originText.ApplyFont(startIndex, startIndex + it.Origin.Length, redFont); + row.CreateCell(3).SetCellValue(originText); + + row.CreateCell(4).SetCellValue(it.Origin); + row.CreateCell(5).SetCellValue(it.Text); + row.CreateCell(6).SetCellValue(StatusText(it.IsAccept)); + id++; + } + + // 保存到文件 + book.Write(fs); + } + } + + + private static ICellStyle CreateBaseCellStyle(IWorkbook workbook) + { + var style = workbook.CreateCellStyle(); + style.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center; + style.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center; + style.WrapText = true; + + return style; + } + private static IFont CreateBaseFont(IWorkbook workbook) + { + // 宋体 11 + var font = workbook.CreateFont(); + font.FontName = "宋体"; + font.FontHeightInPoints = 11; + + return font; + } + + private static string StatusText(int status) + { + if (status == AcceptStatus.Accept) return "采纳"; + else if (status == AcceptStatus.Review) return "采纳"; + else if (status == AcceptStatus.Ignore) return "忽略"; + + return "未处理"; + } } } diff --git a/AIProofread/obj/Debug/AIProofread.csproj.AssemblyReference.cache b/AIProofread/obj/Debug/AIProofread.csproj.AssemblyReference.cache index 83a0140..ded8f79 100644 Binary files a/AIProofread/obj/Debug/AIProofread.csproj.AssemblyReference.cache and b/AIProofread/obj/Debug/AIProofread.csproj.AssemblyReference.cache differ diff --git a/AIProofread/obj/Debug/AIProofread.dll b/AIProofread/obj/Debug/AIProofread.dll index 7343d1a..c518509 100644 Binary files a/AIProofread/obj/Debug/AIProofread.dll and b/AIProofread/obj/Debug/AIProofread.dll differ diff --git a/AIProofread/obj/Debug/AIProofread.pdb b/AIProofread/obj/Debug/AIProofread.pdb index 684a6b0..a662256 100644 Binary files a/AIProofread/obj/Debug/AIProofread.pdb and b/AIProofread/obj/Debug/AIProofread.pdb differ diff --git a/AIProofread/obj/Debug/DesignTimeResolveAssemblyReferences.cache b/AIProofread/obj/Debug/DesignTimeResolveAssemblyReferences.cache index c142275..532afea 100644 Binary files a/AIProofread/obj/Debug/DesignTimeResolveAssemblyReferences.cache and b/AIProofread/obj/Debug/DesignTimeResolveAssemblyReferences.cache differ