Compare commits

...

10 Commits

Author SHA1 Message Date
8ab9a209e5 fixed bug 2024-11-17 11:09:50 +08:00
afddb096b7 fixed 导出提示问题 2024-11-14 20:13:23 +08:00
5b6b615bd2 fixed 自动登录无法关闭窗口 2024-11-13 01:26:32 +08:00
3c0d0f4608 fixed缓存初始化无法找到mark 2024-11-13 01:12:52 +08:00
76147498f4 fixed:新增导致原始内容被覆盖 2024-11-11 21:13:11 +08:00
70c0654a41 保存缓存时 自动保存文档 2024-11-11 17:45:40 +08:00
8ceaf028d8 feat: 调整dialog样式 2024-11-11 17:04:22 +08:00
e58390f7ef 缓存加载时初始化数据无法定位操作状态 2024-11-09 20:14:19 +08:00
7ec0f49aa5 只允许显示一个登录窗口 2024-11-08 22:52:03 +08:00
089e0bc64a 更新数据交互流程;
优化框架架构;
调整数据结构;
2024-11-05 13:40:39 +08:00
75 changed files with 4206 additions and 986 deletions

Binary file not shown.

View File

@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "util-lib", "util-lib\util-l
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "updater", "updater\updater.csproj", "{73AC658D-CD49-4731-8491-A7BDBC811559}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ai-proofread-client", "ai-proofread-client\ai-proofread-client.csproj", "{48C0B207-150A-40B7-9A25-ECF9218FF86F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -42,6 +44,12 @@ Global
{73AC658D-CD49-4731-8491-A7BDBC811559}.Release|Any CPU.Build.0 = Release|Any CPU
{73AC658D-CD49-4731-8491-A7BDBC811559}.Test|Any CPU.ActiveCfg = Debug|Any CPU
{73AC658D-CD49-4731-8491-A7BDBC811559}.Test|Any CPU.Build.0 = Debug|Any CPU
{48C0B207-150A-40B7-9A25-ECF9218FF86F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{48C0B207-150A-40B7-9A25-ECF9218FF86F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48C0B207-150A-40B7-9A25-ECF9218FF86F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48C0B207-150A-40B7-9A25-ECF9218FF86F}.Release|Any CPU.Build.0 = Release|Any CPU
{48C0B207-150A-40B7-9A25-ECF9218FF86F}.Test|Any CPU.ActiveCfg = Debug|Any CPU
{48C0B207-150A-40B7-9A25-ECF9218FF86F}.Test|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -290,12 +290,24 @@
<Compile Include="Controls\FormContact.Designer.cs">
<DependentUpon>FormContact.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FormDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Controls\FormDialog.Designer.cs">
<DependentUpon>FormDialog.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FormLoading.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Controls\FormLoading.Designer.cs">
<DependentUpon>FormLoading.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FormLogger.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Controls\FormLogger.Designer.cs">
<DependentUpon>FormLogger.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FormLogin.cs">
<SubType>Form</SubType>
</Compile>
@ -308,12 +320,30 @@
<Compile Include="Controls\FormMain.Designer.cs">
<DependentUpon>FormMain.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FormMask.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Controls\FormMask.Designer.cs">
<DependentUpon>FormMask.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FormMessage.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Controls\FormMessage.Designer.cs">
<DependentUpon>FormMessage.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FormSetting.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Controls\FormSetting.Designer.cs">
<DependentUpon>FormSetting.cs</DependentUpon>
</Compile>
<Compile Include="Controls\FormWebView.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Controls\FormWebView.Designer.cs">
<DependentUpon>FormWebView.cs</DependentUpon>
</Compile>
<Compile Include="Controls\ProofreadMainControl.cs">
<SubType>UserControl</SubType>
</Compile>
@ -331,7 +361,10 @@
<Compile Include="core\Tools.cs" />
<Compile Include="core\MainPanelWebMessage.cs" />
<Compile Include="Logger.cs" />
<Compile Include="Model\BridgeResult.cs" />
<Compile Include="Model\DocumentContent.cs" />
<Compile Include="Model\DocumentInfo.cs" />
<Compile Include="Model\DocumentList.cs" />
<Compile Include="ProofreadItem.cs" />
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
@ -339,21 +372,37 @@
<Compile Include="Transform.cs" />
<Compile Include="Util\HostHelper.cs" />
<Compile Include="Util\HttpUtil.cs" />
<Compile Include="Util\User32Util.cs" />
<EmbeddedResource Include="Controls\FormContact.resx">
<DependentUpon>FormContact.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormDialog.resx">
<DependentUpon>FormDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormLoading.resx">
<DependentUpon>FormLoading.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormLogger.resx">
<DependentUpon>FormLogger.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormLogin.resx">
<DependentUpon>FormLogin.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormMain.resx">
<DependentUpon>FormMain.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormMask.resx">
<DependentUpon>FormMask.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormMessage.resx">
<DependentUpon>FormMessage.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormSetting.resx">
<DependentUpon>FormSetting.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\FormWebView.resx">
<DependentUpon>FormWebView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\ProofreadMainControl.resx">
<DependentUpon>ProofreadMainControl.cs</DependentUpon>
</EmbeddedResource>
@ -408,7 +457,9 @@
<Name>util-lib</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<ItemGroup>
<None Include="Resources\button.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon-refresh.png" />
</ItemGroup>
@ -421,6 +472,33 @@
<ItemGroup>
<None Include="Resources\icon-save-wps.jpg" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\button_default.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\form_bg.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon-panel-wps.jpg" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon-panel.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon-history-wps.jpg" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon-history.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon-export-wps.jpg" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon-export.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\icon_close.png" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>

View File

@ -8,6 +8,10 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<StartAction>Project</StartAction>
<StartProgram>C:\Soft\Kingsoft\WPS Office\12.1.0.17827\office6\wps.exe</StartProgram>
<StartProgram>C:\Soft\Kingsoft\WPS Office\12.1.0.18608\office6\wps.exe</StartProgram>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<StartAction>Project</StartAction>
<StartProgram>C:\Soft\Kingsoft\WPS Office\12.1.0.18608\office6\wps.exe</StartProgram>
</PropertyGroup>
</Project>

View File

@ -1,11 +1,15 @@
using AIProofread.Controls;
using AIProofread.core;
using AIProofread.Model;
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 NPOI.XSSF.UserModel;
using NPOI.XWPF.UserModel;
using Org.BouncyCastle.Asn1.Crmf;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@ -48,6 +52,15 @@ namespace AIProofread
public void ShowUpgradeView()
{
if (CurrentUpgrade == null)
{
CheckPluginUpgrade();
if (CurrentUpgrade == null)
{
showDialog("获取版本信息失败,请稍后再试");
return;
}
}
var needUpgrade = CurrentUpgrade.NeedUpgrade(Config.APP_VERSION);
if (!needUpgrade)
{
@ -73,7 +86,10 @@ namespace AIProofread
return CurrentUpgrade != null && CurrentUpgrade.NeedUpgrade(Config.APP_VERSION) && CurrentUpgrade.UpgradeType == 1;
}
public void InitPluginUpgrade()
/// <summary>
/// 检查插件更新信息
/// </summary>
public void CheckPluginUpgrade()
{
try
{
@ -85,11 +101,19 @@ namespace AIProofread
CurrentUpgrade = data.Data;
// 是否需要强制升级
//if (ShouldUpgradeForced())
//{
// // 显示升级框
// ShowUpgradeView();
//}
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)
{
@ -99,14 +123,21 @@ namespace AIProofread
public string GetAppVersion()
{
return Config.APP_VERSION;
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();
return JsonConvert.SerializeObject(data);
}
public void SetBtnStatus(string key, bool status)
{
Globals.ThisAddIn.ribbon.SetBtnStatus(key, status);
}
public void showDialog(string message)
public void showDialog(string message, string confirmText = "", string confirmAction = "")
{
System.Windows.Forms.MessageBox.Show(message);
Globals.ThisAddIn.ActiveDocument?.ShowDialog(message, confirmText, confirmAction);
}
public int getMinWIdth()
@ -143,35 +174,26 @@ namespace AIProofread
public void SetDocumentId(int id, Document document)
{
Globals.ThisAddIn.documentIdDics[document] = id;
Globals.ThisAddIn.SetDocumentId(document, id);
}
public Document GetDocumentById(int id)
public DocumentInfo 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;
return Globals.ThisAddIn.GetDocumentById(id);
}
public int GetCurrentDocumentId()
{
return GeIdBytDocument(Globals.ThisAddIn.Application.ActiveDocument);
return Globals.ThisAddIn.ActiveDocument.Id;
}
public int GeIdBytDocument(Document document)
{
if (Globals.ThisAddIn.documentIdDics.ContainsKey(document))
var doc = Globals.ThisAddIn.documentList.Get(document);
if (doc != null)
{
return Globals.ThisAddIn.documentIdDics[document];
return doc.Id;
}
//int id = Globals.ThisAddIn.documentIdDics.Count + 1;
//// 设置文档编号
//SetCurrentDocumentId((int)id);
//return id ;
return 0;
return doc != null ? doc.Id : 0;
}
// 打开网页
@ -187,7 +209,7 @@ namespace AIProofread
}
}
public static void StartUpgradeProcess()
public static void StartUpgradeProcess(bool showFail = true)
{
try
{
@ -202,7 +224,10 @@ namespace AIProofread
catch (Exception e)
{
Logger.Log(e);
MessageBox.Show("启动升级程序失败,请重试");
if (showFail)
{
MessageBox.Show("启动升级程序失败,请重试");
}
}
}
@ -214,26 +239,23 @@ namespace AIProofread
public void ShowCurrentPane()
{
Globals.ThisAddIn.ShowPanel();
//Globals.ThisAddIn.currentDocumentTaskPane.Visible = true;
}
public void HideCurrentPane()
{
Globals.ThisAddIn.HidePanel();
//Globals.ThisAddIn.currentDocumentTaskPane.Visible = false;
}
public void ShowLoginForm(string action)
{
Globals.ThisAddIn.ShowLoginForm(action);
}
public void Logout(string action)
{
if (action == "async-info")
{
// web同步注销到ribbon
Globals.ThisAddIn.SyncLogout();
}
else
{
// ribbon 发送注销动作到 web
Globals.ThisAddIn.SendMessageToWeb("logout", null);
}
// web同步注销到ribbon
Globals.ThisAddIn.SyncLogout();
// ribbon 发送注销动作到 web
Globals.ThisAddIn.SendMessageToWeb("logout", null);
}
/// <summary>
@ -246,7 +268,6 @@ namespace AIProofread
Userinfo info = JsonConvert.DeserializeObject<Userinfo>(userinfo);
// 登录成功 展示
Globals.ThisAddIn.ribbon.ProcessLoginInfo(info);
//Globals.ThisAddIn.SendMessageToWeb("async-login-success", null);
}
// 获取文档所有文本数据
@ -254,18 +275,24 @@ namespace AIProofread
{
return Tools.GetAllText(Globals.ThisAddIn.Application.ActiveDocument);
}
public string getDocumentData()
public bool Saved(int documentId)
{
var document = documentId > 0 ? Globals.ThisAddIn.GetDocumentById(documentId) : Globals.ThisAddIn.ActiveDocument;
return document.CurrentDocument.Saved;
}
/// <summary>
/// 获取文档数据
/// </summary>
/// <returns></returns>
public string getDocumentData(int documentId)
{
Dictionary<string, object> data = new Dictionary<string, object>();
var doc = Globals.ThisAddIn.Application.ActiveDocument;
var documentInfo = documentId > 0 ? Globals.ThisAddIn.GetDocumentById(documentId) : Globals.ThisAddIn.ActiveDocument;
if (!doc.Saved)
{
data.Add("code", 1);
data.Add("message", "请保存文档后再进行校对");
}
else if (ShouldUpgradeForced())
var doc = documentInfo.CurrentDocument;
if (ShouldUpgradeForced())
{
data.Add("code", 2);
data.Add("message", "请升级插件后再进行校对");
@ -277,11 +304,13 @@ namespace AIProofread
}
else
{
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("documentId", GeIdBytDocument(doc));
data.Add("wordsCount", doc.Words.Count);
data.Add("charactersCount", doc.Characters.Count);
data.Add("content", Tools.GetAllText(doc));
@ -289,55 +318,34 @@ namespace AIProofread
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);
}
/// <summary>
/// 获取文档所有段落文本
/// </summary>
/// <returns></returns>
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++)
var doc = Globals.ThisAddIn.ActiveDocument;
if (doc == null)
{
list.Add(GetParagraphText(paragraphs[i]));
return "";
}
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;
return Tools.GetJSONString(doc.GetAllParagraphs());
}
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);
@ -345,47 +353,17 @@ namespace AIProofread
});
}
public int getTotalParagraphNumber()
{
return Globals.ThisAddIn.Application.ActiveDocument.Paragraphs.Count;
}
public int getTotalParagraphNumber() => Globals.ThisAddIn.ActiveDocument?.GetTotalParagraphNumber() ?? -1;
/// <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 string getDocumentFileData() => Globals.ThisAddIn.ActiveDocument?.GetOriginFileData() ?? "";
public void ShowUpgrade(string data)
public void ShowUpgrade(string data, bool force = false)
{
//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();
//}
Globals.ThisAddIn.ActiveDocument.ShowUpgrade(data, force);
}
public void noticeOtherWeb(string json, string targetWebName)
@ -444,54 +422,10 @@ namespace AIProofread
}
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 clearAllProofreadMarkById(int documentId) => Globals.ThisAddIn.GetDocumentById(documentId)?.ClearAllProofreadMark();
public void ClearCurrentDocumentMarks() => Globals.ThisAddIn.ActiveDocument?.ClearAllProofreadMark();
public void removeBookmark(string markId) => DocumentUtil.RemoveBookmark(markId);
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()
{
@ -536,7 +470,6 @@ namespace AIProofread
{
// 文档对象
var document = Globals.ThisAddIn.Application.ActiveDocument;
var vstoDocument = Globals.Factory.GetVstoObject(document);
// 获取选区
var selection = Globals.ThisAddIn.Application.Selection;
// 段落数
@ -592,11 +525,6 @@ namespace AIProofread
}
return text;
}
public void ShowLoginForm(string action)
{
Globals.ThisAddIn.ShowLoginForm(action);
}
public void ShowSettingForm()
{
FormSetting frm = new FormSetting();
@ -611,158 +539,29 @@ namespace AIProofread
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);
Globals.ThisAddIn.ActiveDocument?.SelectMarkById(proofreadId, false);
}
public void processMark(int proofreadId, int status)
{
if (proofreadId > 0 && marks.ContainsKey(proofreadId))
{
marks[proofreadId].Process(status);
}
Globals.ThisAddIn.ActiveDocument?.ProcessMark(proofreadId, status);
}
private Document _currentDocument;
public Document CurrentDocument
{
get => _currentDocument ?? Globals.ThisAddIn.Application.ActiveDocument;
set
{
_currentDocument = value;
}
}
public string InitContent(string content, int documentId)
{
return InitContent(content, documentId, true);
}
public string InitContent(string content, int documentId, bool clearOriginMark)
{
try
{
// 根据文档编号 获取当前文档避免数据混乱
CurrentDocument = GetDocumentById(documentId);
if (CurrentDocument == null)
{
throw new Exception("没有找到校对文档对象");
}
List<CorrectContext> list = JsonConvert.DeserializeObject<List<CorrectContext>>(content);
var document = Globals.ThisAddIn.GetDocumentById(documentId) ?? throw new Exception("没有找到校对文档对象");
// 先清除所有数据
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.CorrectItems != null && correct.CorrectItems.Count > 0)
{
prevOffset = 0;
int index = 0;
foreach (var item in correct.CorrectItems)
{
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);
if (clearOriginMark) document.ClearAllProofreadMark();
List<CorrectContext> list = JsonConvert.DeserializeObject<List<CorrectContext>>(content);
document.InitProofread(list);
}
catch (Exception ex)
{
@ -772,219 +571,167 @@ namespace AIProofread
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;
//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(CorrectItem correct, CorrectContext sentense, ref int prevOffset)
public string MarkSentence(string content, int documentId)
{
// 初始化话
return InitContent(content, documentId, false);
}
public string ShowDialogMessage(string message)
{
var result = FormMessage.ShowMessage(message);
if (result == DialogResult.Retry)
{
return "retry";
}
return "ok";
}
// 保存文件
public string WriteText(string content, string path)
{
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
File.WriteAllText(path, content);
return BridgeResult.Success("ok");
}
catch (Exception ex)
{
Logger.Log("create mark error:" + ex.Message + "\n" + ex.StackTrace + "\n\n");
return BridgeResult.Error(-1, ex.Message);
}
return bookmark;
}
/// <summary>
///
/// </summary>
/// <param name="range"></param>
/// <param name="whatToFind"></param>
private void FindRange(ref Range range, ref object whatToFind)
public string ExportProofreadResult()
{
object matchCase = false; // 是否区分大小写
object matchWholeWord = false; // 是否匹配整个单词
object matchWildcards = false; // 是否使用通配符
object forward = true; // 搜索方向true表示向前搜索false表示向后搜索
object wrap = Microsoft.Office.Interop.Word.WdFindWrap.wdFindContinue; // 搜索范围,这里表示继续搜索
try
{
Globals.ThisAddIn.ActiveDocument.ExportResult();
return BridgeResult.Success();
}
catch (Exception ex)
{
return BridgeResult.Error(-1, ex.Message);
}
}
range.Find.Execute(ref whatToFind, ref matchCase, ref matchWholeWord, ref matchWildcards, ref forward, ref wrap);
public string ReadText(string path)
{
try
{
if (!File.Exists(path)) return BridgeResult.Error(-1, "文件不存在");
return BridgeResult.Success(File.ReadAllText(path));
}
catch (Exception ex)
{
return BridgeResult.Error(-1, ex.Message);
}
}
public void Focus()
{
// 使面板重新获取到焦点
Globals.ThisAddIn.ActiveDocument.FocusToPanel();
}
public string SaveCache(int documentId, string cache, bool silent)
{
var document = Globals.ThisAddIn.GetDocumentById(documentId);
if (!silent)
{
if (!document.CurrentDocument.Saved)
{
MessageBox.Show("请先保存文档");
return BridgeResult.Error(1, "请先保存文档");
}
}
else
{
// 静默时 自动保存文档
document.Save();
}
try
{
Logger.Log("SaveCache " + document.fileName + " used " + document.ProofreadCachePath);
File.WriteAllText(document.ProofreadCachePath, cache);
return BridgeResult.Success("ok");
}
catch (Exception 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.Log("Load cache " + document.fileName + " used " + document.ProofreadCachePath);
try
{
return BridgeResult.Success(File.ReadAllText(document.ProofreadCachePath));
}
catch (Exception 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)
{
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)
{
try
{
List<CorrectContext> list = JsonConvert.DeserializeObject<List<CorrectContext>>(content);
Globals.ThisAddIn.InitProofreadCacheList(list);
return BridgeResult.Success();
}
catch (Exception ex)
{
return BridgeResult.Error(ex);
}
}
public void SetCurrentDocumentProofreadStatus(int documentId,bool status)
{
var document = Globals.ThisAddIn.GetDocumentById(documentId);
document.Proofreading = status;
}
}
}

View File

@ -12,17 +12,22 @@ namespace AIProofread
public class Config
{
public static readonly string APP_NAME = "AI校对王";
public static readonly string APP_VERSION = "1.0.12";
public static readonly string APP_VERSION = "2.0.0";
public static bool IS_WPS = false;
public static bool UpgradeForcedNotice = false;
public static readonly string CONFIG_FILE = AppDomain.CurrentDomain.BaseDirectory + "app.json";
/// <summary>
/// 文本背景色
/// </summary>
public static readonly string TextBackgroundColor = "#D6AA69";
#if DEBUG
/// <summary>
/// 网页访问地址
/// </summary>
public static string WEB_PATH = "http://192.168.10.100:5173/";
public static bool RUN_IN_DEBUG = true;
public static AppEnvironment APP_ENV = AppEnvironment.Dev;
public static string WEB_PATH = "http://192.168.10.100:5173/"; //192.168.0.231:5137 192.168.10.100:5173 gm2-plugin.zverse.group
public static bool RUN_IN_DEBUG = false;
public static AppEnvironment APP_ENV = AppEnvironment.Prod;
#else
public static string WEB_PATH = "https://gm-plugin.gachafun.com/";
public static bool RUN_IN_DEBUG = false;

View File

@ -0,0 +1,111 @@
namespace AIProofread.Controls
{
partial class FormDialog
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.LabelMeesage = new System.Windows.Forms.Label();
this.BtnClose = new System.Windows.Forms.Button();
this.BtnConfirm = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// LabelMeesage
//
this.LabelMeesage.Font = new System.Drawing.Font("微软雅黑", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.LabelMeesage.ForeColor = System.Drawing.Color.Black;
this.LabelMeesage.Location = new System.Drawing.Point(39, 60);
this.LabelMeesage.Name = "LabelMeesage";
this.LabelMeesage.Size = new System.Drawing.Size(346, 70);
this.LabelMeesage.TabIndex = 7;
this.LabelMeesage.Text = "label1";
this.LabelMeesage.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// BtnClose
//
this.BtnClose.BackColor = System.Drawing.Color.White;
this.BtnClose.BackgroundImage = global::AIProofread.Properties.Resources.button_default;
this.BtnClose.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.BtnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.BtnClose.FlatAppearance.BorderColor = System.Drawing.Color.Gainsboro;
this.BtnClose.FlatAppearance.BorderSize = 0;
this.BtnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.BtnClose.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.BtnClose.ForeColor = System.Drawing.Color.Black;
this.BtnClose.Location = new System.Drawing.Point(222, 205);
this.BtnClose.Name = "BtnClose";
this.BtnClose.Size = new System.Drawing.Size(120, 44);
this.BtnClose.TabIndex = 6;
this.BtnClose.Text = "取消";
this.BtnClose.UseVisualStyleBackColor = false;
this.BtnClose.Click += new System.EventHandler(this.BtnClose_Click);
//
// BtnConfirm
//
this.BtnConfirm.BackgroundImage = global::AIProofread.Properties.Resources.button;
this.BtnConfirm.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.BtnConfirm.FlatAppearance.BorderSize = 0;
this.BtnConfirm.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.BtnConfirm.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.BtnConfirm.ForeColor = System.Drawing.Color.White;
this.BtnConfirm.Location = new System.Drawing.Point(78, 205);
this.BtnConfirm.Name = "BtnConfirm";
this.BtnConfirm.Size = new System.Drawing.Size(120, 44);
this.BtnConfirm.TabIndex = 5;
this.BtnConfirm.Text = "确认";
this.BtnConfirm.UseVisualStyleBackColor = true;
this.BtnConfirm.Click += new System.EventHandler(this.button2_Click);
//
// FormDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.CancelButton = this.BtnClose;
this.ClientSize = new System.Drawing.Size(422, 286);
this.Controls.Add(this.LabelMeesage);
this.Controls.Add(this.BtnClose);
this.Controls.Add(this.BtnConfirm);
this.ForeColor = System.Drawing.Color.White;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "FormDialog";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Deactivate += new System.EventHandler(this.FormDialog_Deactivate);
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FormDialog_FormClosed);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label LabelMeesage;
private System.Windows.Forms.Button BtnClose;
private System.Windows.Forms.Button BtnConfirm;
}
}

View File

@ -0,0 +1,70 @@
using AIProofread.Util;
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace AIProofread.Controls
{
public partial class FormDialog : Form
{
public FormDialog()
{
InitializeComponent();
}
private static FormMask mask;
private void SetMessage(string message)
{
LabelMeesage.Text = message;
}
private void SetButtonText(string yesButtonText, string noButtonText)
{
BtnClose.Text = noButtonText;
BtnConfirm.Text = yesButtonText;
}
public static DialogResult Show(string message, string caption, string yesButtonText, string noButtonText)
{
FormDialog formMessage = new FormDialog();
mask = new FormMask(formMessage);
mask.ShowOverWord();
formMessage.SetMessage(message);
formMessage.Text = caption;
formMessage.SetButtonText(yesButtonText, noButtonText);
formMessage.TopMost = true;
IntPtr wordHandle = new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.Hwnd); // 获取Word窗口句柄
User32Util.SetParent(formMessage.Handle,wordHandle);
formMessage.Show();
return DialogResult.Yes;
}
public static DialogResult Show(string message)
{
return Show(message, "", "是", "否");
}
private void BtnClose_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.No;
this.TopMost = false;
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Yes;
this.Close();
}
private void FormDialog_Deactivate(object sender, EventArgs e)
{
// SetForegroundWindow(this.Handle);
// this.Activate();
}
private void FormDialog_FormClosed(object sender, FormClosedEventArgs e)
{
mask.Close();
mask = null;
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,104 @@
namespace AIProofread.Controls
{
partial class FormLogger
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormLogger));
this.LogText = new System.Windows.Forms.RichTextBox();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
this.TsmiClear = new System.Windows.Forms.ToolStripMenuItem();
this.panel1 = new System.Windows.Forms.Panel();
this.contextMenuStrip1.SuspendLayout();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// LogText
//
this.LogText.AutoWordSelection = true;
this.LogText.BackColor = System.Drawing.Color.White;
this.LogText.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.LogText.ContextMenuStrip = this.contextMenuStrip1;
this.LogText.Dock = System.Windows.Forms.DockStyle.Fill;
this.LogText.Font = new System.Drawing.Font("微软雅黑", 7.5F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.LogText.Location = new System.Drawing.Point(0, 0);
this.LogText.Name = "LogText";
this.LogText.ReadOnly = true;
this.LogText.ShowSelectionMargin = true;
this.LogText.Size = new System.Drawing.Size(784, 310);
this.LogText.TabIndex = 0;
this.LogText.Text = "";
//
// contextMenuStrip1
//
this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.TsmiClear});
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(125, 26);
//
// TsmiClear
//
this.TsmiClear.Name = "TsmiClear";
this.TsmiClear.Size = new System.Drawing.Size(124, 22);
this.TsmiClear.Text = "清除日志";
this.TsmiClear.Click += new System.EventHandler(this.TsmiClear_Click);
//
// panel1
//
this.panel1.Controls.Add(this.LogText);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(784, 310);
this.panel1.TabIndex = 1;
//
// FormLogger
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(784, 310);
this.Controls.Add(this.panel1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "FormLogger";
this.Text = "实时日志";
this.TopMost = true;
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FormLogger_FormClosed);
this.contextMenuStrip1.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.RichTextBox LogText;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem TsmiClear;
}
}

View File

@ -0,0 +1,107 @@
using System;
using System.Windows.Forms;
namespace AIProofread.Controls
{
public partial class FormLogger : Form
{
private ListView LogListView;
public FormLogger()
{
InitializeComponent();
//LogListView.View = View.Details;
//LogListView.FullRowSelect = true;
//LogListView.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
}
private void InitLogListView()
{
var columnHeader1 = new ColumnHeader();
var columnHeader2 = new ColumnHeader();
var columnHeader3 = new ColumnHeader();
columnHeader1.Text = "Tag";
columnHeader1.Width = 67;
columnHeader2.Text = "Time";
columnHeader2.Width = 117;
columnHeader3.Text = "Message";
columnHeader3.Width = 480;
LogListView.Columns.AddRange(new ColumnHeader[] {columnHeader1,columnHeader2,columnHeader3});
}
/// <summary>
/// 显示最大日志数
/// </summary>
private const int MaxDisplayItemCount = 100;
public void Log(string time, string tag, string message)
{
ShowLogInText(time, tag, message);
}
private void ShowLogInText(string time, string tag, string message)
{
if (LogText.InvokeRequired)
{
//LogText.Invoke(new AppendLogDel(AppendLog), args);
}
else
{
LogText.AppendText(string.Format("{0} {1} {2}",time,tag,message));
LogText.AppendText(Environment.NewLine);
LogText.ScrollToCaret();
LogText.Update();
}
}
private void ShowLogInList(string time, string tag, string message)
{
if (LogListView.InvokeRequired)
{
LogListView.Invoke(new Action(() => AddLogToList(time, tag, message)));
}
else
{
AddLogToList(time, tag, message);
}
}
private void AddLogToList(string time, string tag, string message)
{
//
ListViewItem insertItem = new ListViewItem(new string[] { tag, time, message });
//
//insertItem.SubItems.Add(time);
//insertItem.SubItems.Add(tag, Color.Violet, Color.White, LogListView.Font);
//insertItem.SubItems.Add(message, Color.Blue, Color.White, LogListView.Font);
//ListViewSubItem tagItem = new ListViewSubItem(insertItem,tag);
//ListViewSubItem timeItem = new ListViewSubItem(insertItem,time, Color.Violet, Color.White, LogListView.Font);
//ListViewSubItem messageItem = new ListViewSubItem(insertItem, time, Color.Blue, Color.White, LogListView.Font);
//insertItem.SubItems.Add(tagItem);
if (LogListView.Items.Count > MaxDisplayItemCount)
{
LogListView.Items.RemoveAt(MaxDisplayItemCount);
}
//ListViewItem lstItem = new ListViewItem(" " + DateTime.Now.ToString(), imageIndex);
//lstItem.SubItems.Add(info);
LogListView.Items.Insert(0, insertItem);
}
private void FormLogger_FormClosed(object sender, FormClosedEventArgs e)
{
Logger.LoggerForm = null;
}
private void TsmiClear_Click(object sender, EventArgs e)
{
LogText.Text = string.Empty;
}
}
}

View File

@ -0,0 +1,196 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAIB4AAAEAIACgDwAAFgAAACgAAAAgAAAAPAAAAAEAIAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAA
AAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAA
AAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPQAA
AJUAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAA
AJgAAACYAAAAmAAAAJgAAACQAAAALQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAB9AAAA/wAAAOoAAADnAAAA5wAAAOcAAADnAAAA5wAAAOcAAADnAAAA5wAAAOcAAADnAAAA5wAA
AOcAAADnAAAA5wAAAOcAAADnAAAA8AAAAPoAAABaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAH4AAADpAAAAQQAAACMAAAAlAAAAJQAAACUAAAAlAAAAJQAAACUAAAAlAAAAJQAA
ACUAAAAlAAAAJQAAACUAAAAlAAAAJQAAACIAAABnAAAA8QAAAFsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAOUAAAAhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEwAAADvAAAAWwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAA5QAAACEAAAAAAAAAVQAAAJwAAABTAAAAAAAA
ADsAAACQAAAAkgAAAJIAAACSAAAAkgAAAJIAAACSAAAAkwAAAEgAAAAAAAAATQAAAO8AAABbAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAADlAAAAIQAAAAAAAACMAAAA/wAA
AIsAAAAAAAAAUwAAAMwAAADPAAAAzwAAAM8AAADPAAAAzwAAAM8AAADQAAAAZgAAAAAAAABNAAAA7wAA
AFsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAOUAAAAhAAAAAAAA
ADsAAABxAAAAPQAAAAAAAAAEAAAACgAAAAoAAAAKAAAACgAAAAoAAAAKAAAACgAAAAoAAAAFAAAAAAAA
AE0AAADvAAAAWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAA5QAA
ACEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAATQAAAO8AAABbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AH8AAADlAAAAIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAABNAAAA7wAAAFsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAfwAAAOUAAAAhAAAAAAAAADkAAABrAAAAOAAAAAAAAAAyAAAAeAAAAHkAAAB5AAAAeQAA
AHkAAAB5AAAAeQAAAHoAAAA+AAAAAAAAAE0AAADvAAAAWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAB/AAAA5QAAACEAAAAAAAAAjQAAAP8AAACLAAAAAAAAAFYAAADYAAAA2wAA
ANsAAADbAAAA2wAAANsAAADbAAAA3AAAAGoAAAAAAAAATQAAAO8AAABbAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAADlAAAAIQAAAAAAAABWAAAAnwAAAFEAAAAAAAAACQAA
ABgAAAAYAAAAGAAAABgAAAAYAAAAGAAAABgAAAAYAAAACwAAAAAAAABNAAAA7wAAAFsAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAOUAAAAhAAAAAAAAAAIAAAAEAAAAAgAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE0AAADvAAAAWwAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/AAAA5QAAACEAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATQAA
AO8AAABbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH8AAADlAAAAIQAA
AAAAAAAkAAAAQAAAACEAAAAAAAAAHQAAAEcAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAAJAAA
AAAAAABNAAAA7wAAAFsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAA
AOUAAAAhAAAAAAAAAIkAAAD8AAAAhAAAAAAAAABhAAAA7wAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAA
APMAAAB3AAAAAAAAAE0AAADvAAAAWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAB/AAAA5QAAACEAAAAAAAAAagAAAMkAAABoAAAAAAAAABUAAAA0AAAANQAAADUAAAA1AAAANQAA
ADUAAAA1AAAANQAAABoAAAAAAAAATQAAAO8AAABbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAH8AAADlAAAAIQAAAAAAAAAJAAAAFAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNAAAA7wAAAFsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAfwAAAOUAAAAiAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAA
AAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAE0AAADvAAAAWwAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB9AAAA9wAAAKkAAACbAAAAnAAAAJwAAACcAAAAnAAA
AJwAAACcAAAAnAAAAJwAAACcAAAAnAAAAJwAAACcAAAAnAAAAJwAAACbAAAAuQAAAPUAAABbAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGkAAADhAAAA4gAAAOIAAADiAAAA4gAA
AOIAAADiAAAA4gAAAOIAAADiAAAA4gAAAOIAAADiAAAA4gAAAOIAAADiAAAA4gAAAOIAAADiAAAA2AAA
AEwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAACUAAAAmAAAAJgAA
ACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAAACYAAAAmAAAAJgAA
ACYAAAAkAAAACQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAD////////////////8AAA/+AAAH/gAAB/4AAAf+P//H/iIAR/4iAEf+IgBH/j//x/4//8f+IgBH/iI
AR/4iAEf+I//H/j//x/4iAEf+IgBH/iIAR/4j/8f+PABH/gAAB/4AAAf+AAAH///////////////////
//8=
</value>
</data>
</root>

View File

@ -0,0 +1,48 @@
namespace AIProofread.Controls
{
partial class FormMask
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// FormMask
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Name = "FormMask";
this.Opacity = 0.1D;
this.Text = "FormMask";
this.ResumeLayout(false);
}
#endregion
}
}

View File

@ -0,0 +1,46 @@
using AIProofread.Util;
using System;
using System.Drawing;
using System.Windows.Forms;
namespace AIProofread.Controls
{
public partial class FormMask : Form
{
public Form myParent;
public FormMask(Form myParent)
{
//InitializeComponent();
this.myParent = myParent;
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = Color.Black;
this.Opacity = 0.5; // 设置遮罩透明度
this.ShowInTaskbar = false;
this.StartPosition = FormStartPosition.Manual;
this.WindowState = FormWindowState.Maximized;
this.Click += FormMask_Click;
//this.TopMost = true;
}
private void FormMask_Click(object sender, EventArgs e)
{
User32Util.SetForegroundWindow(myParent.Handle);
myParent.Focus();
}
public void ShowOverWord()
{
IntPtr wordHandle = new IntPtr(Globals.ThisAddIn.Application.ActiveWindow.Hwnd); // 获取Word窗口句柄
// User32Util.SetParent(this.Handle, wordHandle);
var wordRect = new User32Util.RECT();
User32Util.GetWindowRect(wordHandle, ref wordRect);
// 设置遮罩窗体的位置和大小
this.Bounds = new Rectangle(wordRect.Left, wordRect.Top,
wordRect.Right - wordRect.Left,
wordRect.Bottom - wordRect.Top);
this.Show();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,155 @@
namespace AIProofread.Controls
{
partial class FormMessage
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.LblMeesage = new System.Windows.Forms.Label();
this.IconClose = new System.Windows.Forms.PictureBox();
this.panel1 = new System.Windows.Forms.Panel();
this.label1 = new System.Windows.Forms.Label();
this.BtnClose = new System.Windows.Forms.Button();
this.BtnConfirm = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.IconClose)).BeginInit();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// LblMeesage
//
this.LblMeesage.BackColor = System.Drawing.Color.Transparent;
this.LblMeesage.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.LblMeesage.Location = new System.Drawing.Point(30, 60);
this.LblMeesage.Name = "LblMeesage";
this.LblMeesage.Size = new System.Drawing.Size(320, 140);
this.LblMeesage.TabIndex = 4;
this.LblMeesage.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// IconClose
//
this.IconClose.BackColor = System.Drawing.Color.Transparent;
this.IconClose.Cursor = System.Windows.Forms.Cursors.Hand;
this.IconClose.Image = global::AIProofread.Properties.Resources.icon_close;
this.IconClose.Location = new System.Drawing.Point(350, 15);
this.IconClose.Name = "IconClose";
this.IconClose.Size = new System.Drawing.Size(16, 16);
this.IconClose.TabIndex = 1;
this.IconClose.TabStop = false;
this.IconClose.Click += new System.EventHandler(this.IconClose_Click);
//
// panel1
//
this.panel1.BackgroundImage = global::AIProofread.Properties.Resources.form_bg;
this.panel1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.panel1.Controls.Add(this.IconClose);
this.panel1.Controls.Add(this.label1);
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(380, 46);
this.panel1.TabIndex = 3;
//
// label1
//
this.label1.AutoSize = true;
this.label1.BackColor = System.Drawing.Color.Transparent;
this.label1.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.label1.Location = new System.Drawing.Point(11, 12);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(74, 21);
this.label1.TabIndex = 0;
this.label1.Text = "温馨提示";
//
// BtnClose
//
this.BtnClose.BackColor = System.Drawing.Color.White;
this.BtnClose.BackgroundImage = global::AIProofread.Properties.Resources.button_default;
this.BtnClose.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.BtnClose.Cursor = System.Windows.Forms.Cursors.Hand;
this.BtnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.BtnClose.FlatAppearance.BorderColor = System.Drawing.Color.Gainsboro;
this.BtnClose.FlatAppearance.BorderSize = 0;
this.BtnClose.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent;
this.BtnClose.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent;
this.BtnClose.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.BtnClose.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.BtnClose.ForeColor = System.Drawing.Color.Black;
this.BtnClose.Location = new System.Drawing.Point(200, 214);
this.BtnClose.Name = "BtnClose";
this.BtnClose.Size = new System.Drawing.Size(120, 44);
this.BtnClose.TabIndex = 2;
this.BtnClose.Text = "关闭";
this.BtnClose.UseVisualStyleBackColor = false;
this.BtnClose.Click += new System.EventHandler(this.BtnClose_Click);
//
// BtnConfirm
//
this.BtnConfirm.BackgroundImage = global::AIProofread.Properties.Resources.button;
this.BtnConfirm.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.BtnConfirm.Cursor = System.Windows.Forms.Cursors.Hand;
this.BtnConfirm.DialogResult = System.Windows.Forms.DialogResult.OK;
this.BtnConfirm.FlatAppearance.BorderSize = 0;
this.BtnConfirm.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent;
this.BtnConfirm.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent;
this.BtnConfirm.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.BtnConfirm.Font = new System.Drawing.Font("微软雅黑", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.BtnConfirm.ForeColor = System.Drawing.Color.White;
this.BtnConfirm.Location = new System.Drawing.Point(60, 214);
this.BtnConfirm.Name = "BtnConfirm";
this.BtnConfirm.Size = new System.Drawing.Size(120, 44);
this.BtnConfirm.TabIndex = 1;
this.BtnConfirm.Text = "重新校对";
this.BtnConfirm.UseVisualStyleBackColor = true;
this.BtnConfirm.Click += new System.EventHandler(this.BtnConfirm_Click);
//
// FormMessage
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(380, 286);
this.Controls.Add(this.LblMeesage);
this.Controls.Add(this.panel1);
this.Controls.Add(this.BtnClose);
this.Controls.Add(this.BtnConfirm);
this.Name = "FormMessage";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "FormMessage";
((System.ComponentModel.ISupportInitialize)(this.IconClose)).EndInit();
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button BtnConfirm;
private System.Windows.Forms.Button BtnClose;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label LblMeesage;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.PictureBox IconClose;
}
}

View File

@ -0,0 +1,85 @@
using System;
using System.Windows.Forms;
namespace AIProofread.Controls
{
public partial class FormMessage : BaseWinForm
{
public FormMessage()
{
InitializeComponent();
}
private void SetMessage(string message)
{
LblMeesage.Text = message;
}
private string currentConfirmText;
private string currentConfirmAction;
private void SetConfirmText(string confirmText)
{
currentConfirmText = confirmText;
if (confirmText == "proofread")
{
confirmText = "重新校对";
}
BtnConfirm.Text = confirmText;
BtnConfirm.Visible = true;
BtnConfirm.Enabled = true;
}
private void HideConfirm()
{
BtnConfirm.Visible = false;
BtnConfirm.Enabled = false;
BtnClose.Location = new System.Drawing.Point((
(this.Width - BtnClose.Width) / 2
), BtnClose.Location.Y);
}
private void ResetButtons()
{
BtnClose.Location = new System.Drawing.Point(200, BtnClose.Location.Y);
BtnConfirm.Location = new System.Drawing.Point(60, BtnConfirm.Location.Y);
BtnConfirm.Visible = true;
BtnConfirm.Enabled = true;
}
public static DialogResult ShowMessage(string message,string confirmText = "确认",string confirmAction = null)
{
FormMessage formMessage = new FormMessage();
formMessage.SetMessage(message);
formMessage.currentConfirmAction = confirmAction;
if(string.IsNullOrEmpty(confirmText))
{
formMessage.HideConfirm();
}
else
{
formMessage.ResetButtons();
}
return formMessage.ShowDialog();
}
private void BtnClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void BtnConfirm_Click(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(currentConfirmAction))
{
string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
Globals.ThisAddIn.SendMessageToWeb(currentConfirmAction, time);
}
this.Close();
}
private void IconClose_Click(object sender, EventArgs e)
{
this.Close();
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,66 @@
namespace AIProofread.Controls
{
partial class FormWebView
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.WebView = new Microsoft.Web.WebView2.WinForms.WebView2();
((System.ComponentModel.ISupportInitialize)(this.WebView)).BeginInit();
this.SuspendLayout();
//
// WebView
//
this.WebView.AllowExternalDrop = true;
this.WebView.CreationProperties = null;
this.WebView.DefaultBackgroundColor = System.Drawing.Color.White;
this.WebView.Dock = System.Windows.Forms.DockStyle.Fill;
this.WebView.Location = new System.Drawing.Point(0, 0);
this.WebView.Name = "WebView";
this.WebView.Size = new System.Drawing.Size(800, 450);
this.WebView.TabIndex = 0;
this.WebView.ZoomFactor = 1D;
//
// FormWebView
//
this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.WebView);
this.Name = "FormWebView";
this.Text = "FormWebView";
this.Load += new System.EventHandler(this.FormWebView_Load);
((System.ComponentModel.ISupportInitialize)(this.WebView)).EndInit();
this.ResumeLayout(false);
}
#endregion
private Microsoft.Web.WebView2.WinForms.WebView2 WebView;
}
}

View File

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AIProofread.Controls
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public partial class FormWebView : BaseWinForm
{
public string WebUrl { get; set; }
public FormWebView(string url,int width,int height)
{
InitializeComponent();
this.WebUrl = url;
this.SetSize(width, height);
}
public void SetSize(int width, int height)
{
this.Width = width;
this.Height = height;
}
private void FormWebView_Load(object sender, EventArgs e)
{
// 初始化
InitWebView(WebView,this.WebUrl, "webview");
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -7,15 +7,9 @@ namespace AIProofread.Controls
{
public partial class ProofreadMainControl : UserControl
{
private Document doc;
private int minWidth;
public ProofreadMainControl(Document doc,int minWidth)
public ProofreadMainControl()
{
InitializeComponent();
this.doc = doc;
this.minWidth = minWidth;
Bridge.InitWebEnvAsync("main", web);
//this.minWidth = 420 * LabelWidth() / 42;
@ -25,17 +19,17 @@ namespace AIProofread.Controls
private void ProofreadMainControl_Load(object sender, EventArgs e)
{
this.web.Source = new Uri(Config.WebPath("home?version=" + Config.APP_VERSION + "&t=" + DateTime.Now.Ticks));
this.web.Source = new Uri(Config.WebPath("correct?version=" + Config.APP_VERSION + "&t=" + DateTime.Now.Ticks));
//this.SizeChanged += ProofreadMainControl_SizeChanged;
}
private void ProofreadMainControl_SizeChanged(object sender, EventArgs e)
{
if(this.minWidth > 0 && this.Width < this.minWidth)
{
SendKeys.Send("{ESC}");
this.Width = this.minWidth;
}
//if(this.minWidth > 0 && this.Width < this.minWidth)
//{
// SendKeys.Send("{ESC}");
// this.Width = this.minWidth;
//}
}
public int LabelWidth()
{

View File

@ -1,43 +1,55 @@
using System;
using AIProofread.Controls;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Interop;
namespace AIProofread
{
public class Logger
{
private static readonly string AppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
public static FormLogger LoggerForm;
//private static readonly string AppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
/// <summary>
///
/// </summary>
/// <param name="msg"></param>
public static void Log(string msg)
public static void Log(string tag,string message)
{
string time = DateTime.Now.ToString("HH:mm:ss");
// 如果日志窗口已经打开,则显示日志
if (LoggerForm != null && !LoggerForm.IsDisposed && LoggerForm.Visible)
{
LoggerForm.Log(time, tag, message);
return;
}
string path = Config.APP_LOG_PATH + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
if (!Directory.Exists(Config.APP_LOG_PATH))
{
Directory.CreateDirectory(Config.APP_LOG_PATH);
}
StreamWriter streamWriter = File.AppendText(path);
streamWriter.WriteLine("***************************[" + (Config.IS_WPS ? "WPS" : "WORD") + "]***************************");
streamWriter.WriteLine("消息:" + msg);
streamWriter.WriteLine("时间:" + DateTime.Now.ToString("HH:mm:ss"));
streamWriter.WriteLine("***************************[" + tag + "]***************************");
streamWriter.WriteLine("消息:" + message);
streamWriter.WriteLine("时间:" + time);
streamWriter.WriteLine();
streamWriter.Flush();
streamWriter.Close();
streamWriter.Dispose();
}
public static void Log( Exception e)
public static void Log(string msg)
{
Log((Config.IS_WPS ? "WPS" : "WORD"), msg);
}
public static void Log(Exception e)
{
Log(e.Message + "\n" + e.StackTrace);
}
public static void Log(string tag, Exception e)
{
Log(tag + "\n" + e.StackTrace);
Log(tag,e.Message + "\n" + e.StackTrace);
}
public static void LogToWeb(string msg)

View File

@ -0,0 +1,47 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AIProofread.Model
{
class BridgeResultModel
{
[JsonProperty("code")]
public int Code { get; set; }
[JsonProperty("message")]
public string Message { get; set; }
[JsonProperty("data")]
public object Data { get; set; }
}
public class BridgeResult
{
public static string Error()
{
return Error(-1, "error");
}
public static string Error(Exception ex)
{
return Error(-1, ex.Message);
}
public static string Error(string message)
{
return Error(-1, message);
}
public static string Error(int code, string message)
{
return JsonConvert.SerializeObject(new BridgeResultModel() { Code = code, Message = message });
}
public static string Success()
{
return Success(null);
}
public static string Success(object data)
{
return JsonConvert.SerializeObject(new BridgeResultModel() { Code = 0, Data = data, Message = "success" });
}
}
}

View File

@ -0,0 +1,21 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AIProofread.Model
{
public class DocumentContent
{
[JsonProperty("origin")]
public string[] OriginCut { get; set; }
[JsonProperty("trim_cut")]
public string[] TrimCut { get; set; }
[JsonProperty("paragraphs")]
public string[] Paragraphs { get; set; }
}
}

View File

@ -1,11 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Core;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using AIProofread.Controls;
using AIProofread.core;
using AIProofread.Util;
using Microsoft.Office.Interop.Word;
using Newtonsoft.Json;
using UtilLib;
using CustomTaskPane = Microsoft.Office.Tools.CustomTaskPane;
namespace AIProofread.Model
{
@ -14,18 +19,149 @@ namespace AIProofread.Model
/// </summary>
public class DocumentInfo
{
public static readonly int MIN_WIDTH = 420;
private static char[] ArticleSpecialChars = new char[4] { '\a', '\r', '\v', '\f' };
//private Document currentDocument;
public Document CurrentDocument { get; set; }
private string fileName;
private string uniqueId;
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>();
public string UniqueId
{
get { return uniqueId; }
/// <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; }
public bool PaneVisible { get; set; }
public int Id { get; set; }
public CustomTaskPane TaskPane { get; set; }
public WdProtectionType ProtectionType { get { return CurrentDocument.ProtectionType; } }
public bool Proofreading { get; set; }
// 初始化
public DocumentInfo(Document doc)
{
this.CurrentDocument = doc;
Initialize();
}
/// <summary>
/// 显示面板
/// </summary>
public void ShowPane()
{
if (null != TaskPane)
{
TaskPane.Visible = PaneVisible = true;
}
}
public void ShowDialog(string message, string confirmText, string confirmAction)
{
TaskPane.Control.BeginInvoke(new Action(() =>
{
//MessageBox.Show(message, "提示");
FormMessage.ShowMessage(message, confirmText, confirmAction);
}));
}
public void ShowLogin(string action)
{
TaskPane.Control.BeginInvoke(new Action(() =>
{
FormLogin frm = new FormLogin(action);
Globals.ThisAddIn.LoginFormList.Add(frm);
frm.ShowDialog();
}));
}
/// <summary>
/// 隐藏面板
/// </summary>
public void HidePane()
{
if (null != TaskPane) TaskPane.Visible = PaneVisible = false;
}
/// <summary>
/// 激活
/// </summary>
public void Active()
{
IsActive = true;
if (null != TaskPane && PaneVisible)
{
TaskPane.Visible = true;
}
}
public void Deactive()
{
IsActive = false;
if (null != TaskPane && PaneVisible)
{
TaskPane.Visible = false;
}
}
public void Dispose()
{
try
{
ProofreadMainControl control = (ProofreadMainControl)TaskPane.Control;
control.ResetWeb();
HidePane();
TaskPane?.Dispose();
}
catch (Exception e)
{
Logger.Log("Error", e);
}
}
// 计算uniqueId
@ -40,16 +176,68 @@ namespace AIProofread.Model
uniqueId = filename.GetHashCode().ToString();
}
// 初始化
public DocumentInfo(Document doc)
/// <summary>
/// 添加变量控制重复调用
/// </summary>
private bool isResizing = false;
private void Control_SizeChanged(object sender, EventArgs e)
{
this.CurrentDocument = doc;
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()
{
var control = new ProofreadMainControl();
if (MinWidth < 10)
{
MinWidth = MIN_WIDTH * control.LabelWidth() / 42;
}
// 创建pane
TaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(control, " ");
// 默认隐藏
TaskPane.Visible = false;
// 设置宽度
control.Width = MinWidth;
TaskPane.Width = MinWidth;
// 监听尺寸变化 防止最小尺寸小于设置值
control.SizeChanged += Control_SizeChanged;
TaskPane.VisibleChanged += TaskPane_VisibleChanged;
}
public void CheckBtnStatus()
{
//
if (Globals.ThisAddIn.ribbon != null)
{
Globals.ThisAddIn.ribbon.BtnShowPanel.Enabled = !PaneVisible && marks.Count > 0;
Globals.ThisAddIn.ribbon.SetCommonBtnStatus(!Proofreading);
}
}
private void TaskPane_VisibleChanged(object sender, EventArgs e)
{
// 如果已经隐藏 则记录隐藏用于(WPS)多面板的切换的处理
PaneVisible = TaskPane.Visible;
CheckBtnStatus();
}
public void Initialize()
{
this.fileName = CurrentDocument.FullName;
ranges.Clear();
ComputeUniqueId();
if (TaskPane == null) CreateTaskPane();
}
//处理文档选区时 判断当前选区是否有校对项 有则选择该范围
@ -103,6 +291,34 @@ namespace AIProofread.Model
return string.IsNullOrEmpty(text) ? "" : text;
}
/// <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)
{
@ -115,7 +331,7 @@ namespace AIProofread.Model
{
foreach (var correct in item.CorrectItems)
{
var range = LocateProofreadItem(correct,item,ref prevOffset);
var range = LocateProofreadItem(correct, item, ref prevOffset);
if (range == null) continue;
}
@ -149,10 +365,12 @@ namespace AIProofread.Model
var paraText = paraRange.Text;
var paraStart = paraRange.Start;
var offset = paraStart + ctx.SentenceOffset;
//var offset = paraStart + ctx.SentenceOffset;
//var cutLength = Math.Min(c.InsertLen, paraText.Length - offset);
var sentence = paraText.Substring(ctx.SentenceOffset, ctx.InsertLength);
if (sentence == ctx.Insert)
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);
//
@ -221,8 +439,393 @@ namespace AIProofread.Model
}
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)
{
Logger.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)
{
Logger.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;
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);
}
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>();
foreach (var correct in list)
{
Logger.Log(string.Format("correct content:", correct.Insert));
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;
// 查找对应区域并再该区域添加书签
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, 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(Config.TextBackgroundColor));
// 给选区添加背景颜色
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
{
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);
}
public void InitProofreadCache(List<CorrectContext> list)
{
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);
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);
}
internal void ProcessMark(int proofreadId, int status)
{
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;
}
public void Save()
{
CurrentDocument.Save();
}
public void FocusToPanel()
{
TaskPane.Visible = true;
TaskPane.Control.Focus();
}
internal void Close()
{
try
{
marks.Clear();
ranges.Clear();
TaskPane.Dispose();
}
catch (Exception ex)
{
Logger.Log(ex);
}
}
public void ExportResult()
{
TaskPane.Control.BeginInvoke(new Action(() =>
{
DocumentUtil.ExportProofreadResult();
}));
}
internal 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();
}
}));
}
}
}

View File

@ -0,0 +1,139 @@
using Microsoft.Office.Interop.Word;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AIProofread.Model
{
/// <summary>
/// 文档列表
/// </summary>
public class DocumentList
{
public List<DocumentInfo> documentList = new List<DocumentInfo>();
public DocumentInfo ActiveDocument { get; set; }
public int Count => documentList.Count;
public void Add(DocumentInfo documentInfo)
{
documentList.Add(documentInfo);
}
public void Clear()
{
documentList.ForEach(doc =>{ doc.Dispose(); });
documentList.Clear();
}
public DocumentInfo Get(int index)
{
return documentList[index];
}
public DocumentInfo GetById(int id)
{
return Count > 0 ? documentList.FirstOrDefault(x => x.Id == id) : null;
}
public DocumentInfo Get(string uniqueId)
{
return Count > 0 ? documentList.FirstOrDefault(x => x.UniqueId == uniqueId) : null;
}
public DocumentInfo Get(Document doc)
{
return Count > 0 && doc != null ? documentList.FirstOrDefault(x => x.CurrentDocument == doc) : null;
}
public DocumentInfo GetActive()
{
// documentList.FirstOrDefault(x => x.IsActive)
return Count > 0 ? ActiveDocument : null;
}
public bool Contains(DocumentInfo documentInfo)
{
return Count > 0 && documentList.Contains(documentInfo);
}
public bool Contains(string uniqueId)
{
return Count > 0 && documentList.Any(x => x.UniqueId == uniqueId);
}
// 通过文档判断是否包含
public bool Contains(Document originDocument)
{
return Count > 0 && originDocument != null && documentList.Any(x => x.CurrentDocument == originDocument);
}
/// <summary>
/// 移除文档
/// </summary>
/// <param name="documentInfo"></param>
/// <returns></returns>
public bool Remove(DocumentInfo documentInfo)
{
return documentList.Remove(documentInfo);
}
public bool Remove(Document originDocument)
{
if(Count > 0 && originDocument != null)
{
documentList.RemoveAll(x =>
{
if(x.CurrentDocument == originDocument)
{
x.Close();
return true;
}
return false;
});
}
return true;
}
/// <summary>
/// 获取文档的索引
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public int IndexOf(DocumentInfo item)
{
return documentList.IndexOf(item);
}
/// <summary>
/// 设置当前激活的文档
/// </summary>
/// <param name="originDocument"></param>
public DocumentInfo SetActiveDocument(Document originDocument)
{
if (originDocument == null) return null;
var document = Get(originDocument);
// 如果不存在,则添加
if (document == null)
{
document = new DocumentInfo(originDocument);
Add(document);
}
if (ActiveDocument == document) return document;
else if (Globals.ThisAddIn.IsWPS)
{
// WPS 只有一个窗口 所以需要先关闭之前文档的面板
ActiveDocument?.Deactive();
}
// 如果存在,则设置激活
ActiveDocument = document;
//document.IsActive = true;
document.Active();
return document;
}
internal void HideAllPane()
{
documentList.ForEach(d => d.HidePane());
}
}
}

View File

@ -8,9 +8,11 @@ using Bookmark = Microsoft.Office.Tools.Word.Bookmark;
namespace UtilLib
{
public class ProofreadItem
{
public Bookmark mark;
public string OriginSentence { get; set; }
public CorrectItem content;
private float originSize;
private WdColor originColor;
@ -18,10 +20,11 @@ namespace UtilLib
public string Name { get; set; }
public int DocumentId { get; set; }
public ProofreadItem(CorrectItem content,int documentId)
public ProofreadItem(CorrectItem content,string originSentence,int documentId)
{
this.content = content;
this.DocumentId = documentId;
this.OriginSentence = originSentence;
InitBookMark(null);
SetMarkName();
}
@ -31,9 +34,10 @@ namespace UtilLib
this.Name = this.mark != null ? mark.Name : Config.BuildBookmarkName(content.Id);
}
public ProofreadItem(CorrectItem content, Bookmark bookmark, int documentId)
public ProofreadItem(CorrectItem content, string originSentence, Bookmark bookmark, int documentId)
{
this.DocumentId = documentId;
this.OriginSentence = originSentence;
this.content = content;
if (bookmark != null)
{
@ -79,7 +83,7 @@ namespace UtilLib
{
if (mark == null) return;
mark.Range.Font.Size = originSize + 2; // 将选中标签文本放大字体
mark.Select();
//mark.Select();
}
public void UnSelect()
@ -101,8 +105,11 @@ namespace UtilLib
try
{
if (mark == null) return;
//mark.Range.Underline = Microsoft.Office.Interop.Word.WdUnderline.wdUnderlineThick;
mark.Shading.BackgroundPatternColor = (WdColor)ColorTranslator.ToOle(Colors.FromHex(content.Color));
// 颜色转码
var color = (WdColor)ColorTranslator.ToOle(Colors.FromHex(Config.TextBackgroundColor));
// 给选区添加背景颜色
mark.Shading.BackgroundPatternColor = color;
}
catch (Exception e)
{
@ -157,6 +164,7 @@ namespace UtilLib
}
else if (status == AcceptStatus.Default)
{
// 撤销
if (content.Tag == "r" || content.Tag == "d")
{
mark.Text = content.Origin;

View File

@ -60,6 +60,26 @@ namespace AIProofread.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap button {
get {
object obj = ResourceManager.GetObject("button", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap button_default {
get {
object obj = ResourceManager.GetObject("button_default", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -70,6 +90,16 @@ namespace AIProofread.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap form_bg {
get {
object obj = ResourceManager.GetObject("form_bg", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -110,6 +140,56 @@ namespace AIProofread.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap icon_close {
get {
object obj = ResourceManager.GetObject("icon_close", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap icon_export {
get {
object obj = ResourceManager.GetObject("icon-export", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap icon_export_wps {
get {
object obj = ResourceManager.GetObject("icon-export-wps", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap icon_history {
get {
object obj = ResourceManager.GetObject("icon-history", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap icon_history_wps {
get {
object obj = ResourceManager.GetObject("icon-history-wps", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
@ -130,6 +210,26 @@ namespace AIProofread.Properties {
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap icon_panel {
get {
object obj = ResourceManager.GetObject("icon-panel", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap icon_panel_wps {
get {
object obj = ResourceManager.GetObject("icon-panel-wps", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>

View File

@ -118,67 +118,97 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="icon-proofread" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-proofread.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-setting-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-setting-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-logout" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-logout.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-phone-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-phone-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-user-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-user-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-setting" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-setting.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-phone" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-phone.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-book-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-book-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-proofread-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-proofread-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-update-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-update-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-book" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-book.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="favicon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\favicon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-clear" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-clear.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-clear-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-clear-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-logout-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-logout-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-update" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-update.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-user" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-user.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-refresh" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-refresh.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<data name="icon-save-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-save-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-refresh-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-refresh-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<data name="icon-proofread-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-proofread-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="button" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\button.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-proofread" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-proofread.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-phone" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-phone.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-user-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-user-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="form_bg" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\form_bg.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-save" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-save.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-save-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-save-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<data name="icon-logout-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-logout-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-book-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-book-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-update-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-update-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-setting" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-setting.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-update" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-update.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-clear-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-clear-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-book" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-book.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-panel-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-panel-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="favicon" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\favicon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-refresh-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-refresh-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-export" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-export.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="button_default" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\button_default.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-export-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-export-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-refresh" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-refresh.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-clear" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-clear.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-phone-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-phone-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-history-wps" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-history-wps.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-logout" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-logout.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-history" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-history.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon-panel" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon-panel.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="icon_close" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\icon_close.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 980 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 B

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 B

View File

@ -36,9 +36,13 @@ namespace AIProofread
/// </summary>
private void InitializeComponent()
{
Microsoft.Office.Tools.Ribbon.RibbonDropDownItem ribbonDropDownItemImpl1 = this.Factory.CreateRibbonDropDownItem();
Microsoft.Office.Tools.Ribbon.RibbonDropDownItem ribbonDropDownItemImpl2 = this.Factory.CreateRibbonDropDownItem();
Microsoft.Office.Tools.Ribbon.RibbonDropDownItem ribbonDropDownItemImpl3 = this.Factory.CreateRibbonDropDownItem();
this.tabAIProofread = this.Factory.CreateRibbonTab();
this.group1 = this.Factory.CreateRibbonGroup();
this.BtnProofreadAll = this.Factory.CreateRibbonButton();
this.BtnExportProofreadResult = this.Factory.CreateRibbonButton();
this.btnClear = this.Factory.CreateRibbonButton();
this.btnOpenLexicon = this.Factory.CreateRibbonButton();
this.btnSetting = this.Factory.CreateRibbonButton();
@ -51,14 +55,22 @@ namespace AIProofread
this.Group = this.Factory.CreateRibbonGroup();
this.ButtonSaveCache = this.Factory.CreateRibbonButton();
this.ButtonLoadCache = this.Factory.CreateRibbonButton();
this.group2 = this.Factory.CreateRibbonGroup();
this.BtnShowPanel = this.Factory.CreateRibbonButton();
this.grpDebug = this.Factory.CreateRibbonGroup();
this.btnShowPane = this.Factory.CreateRibbonButton();
this.btnHidePane = this.Factory.CreateRibbonButton();
this.BtnOpenLog = this.Factory.CreateRibbonButton();
this.button1 = this.Factory.CreateRibbonButton();
this.BtnOpenLogger = this.Factory.CreateRibbonButton();
this.BtnTest = this.Factory.CreateRibbonButton();
this.BtnOpenAppDir = this.Factory.CreateRibbonButton();
this.BtnShowVersion = this.Factory.CreateRibbonButton();
this.dropDown1 = this.Factory.CreateRibbonDropDown();
this.tabAIProofread.SuspendLayout();
this.group1.SuspendLayout();
this.Group.SuspendLayout();
this.group2.SuspendLayout();
this.grpDebug.SuspendLayout();
this.SuspendLayout();
//
@ -66,6 +78,7 @@ namespace AIProofread
//
this.tabAIProofread.Groups.Add(this.group1);
this.tabAIProofread.Groups.Add(this.Group);
this.tabAIProofread.Groups.Add(this.group2);
this.tabAIProofread.Groups.Add(this.grpDebug);
this.tabAIProofread.Label = "AI校对王";
this.tabAIProofread.Name = "tabAIProofread";
@ -74,6 +87,7 @@ namespace AIProofread
// group1
//
this.group1.Items.Add(this.BtnProofreadAll);
this.group1.Items.Add(this.BtnExportProofreadResult);
this.group1.Items.Add(this.btnClear);
this.group1.Items.Add(this.btnOpenLexicon);
this.group1.Items.Add(this.btnSetting);
@ -89,16 +103,25 @@ namespace AIProofread
//
this.BtnProofreadAll.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.BtnProofreadAll.Image = global::AIProofread.Properties.Resources.icon_proofread;
this.BtnProofreadAll.Label = "全文校对\n";
this.BtnProofreadAll.Label = "全文校对\r\n";
this.BtnProofreadAll.Name = "BtnProofreadAll";
this.BtnProofreadAll.ShowImage = true;
this.BtnProofreadAll.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnProofreadAll_Click);
//
// BtnExportProofreadResult
//
this.BtnExportProofreadResult.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.BtnExportProofreadResult.Image = global::AIProofread.Properties.Resources.icon_export;
this.BtnExportProofreadResult.Label = "导出勘误表\r\n";
this.BtnExportProofreadResult.Name = "BtnExportProofreadResult";
this.BtnExportProofreadResult.ShowImage = true;
this.BtnExportProofreadResult.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnExportProofreadResult_Click);
//
// btnClear
//
this.btnClear.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.btnClear.Image = global::AIProofread.Properties.Resources.icon_clear;
this.btnClear.Label = "清除标注\n";
this.btnClear.Label = "清除标注\r\n";
this.btnClear.Name = "btnClear";
this.btnClear.ShowImage = true;
this.btnClear.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btnClear_Click);
@ -107,7 +130,7 @@ namespace AIProofread
//
this.btnOpenLexicon.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.btnOpenLexicon.Image = global::AIProofread.Properties.Resources.icon_book;
this.btnOpenLexicon.Label = "词库管理\n";
this.btnOpenLexicon.Label = "词库管理\r\n";
this.btnOpenLexicon.Name = "btnOpenLexicon";
this.btnOpenLexicon.ShowImage = true;
this.btnOpenLexicon.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btnOpenLexicon_Click);
@ -116,7 +139,7 @@ namespace AIProofread
//
this.btnSetting.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.btnSetting.Image = global::AIProofread.Properties.Resources.icon_setting;
this.btnSetting.Label = "插件设置\n";
this.btnSetting.Label = "插件设置\r\n";
this.btnSetting.Name = "btnSetting";
this.btnSetting.ShowImage = true;
this.btnSetting.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btnSetting_Click);
@ -125,7 +148,7 @@ namespace AIProofread
//
this.BtnGetContact.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.BtnGetContact.Image = global::AIProofread.Properties.Resources.icon_phone;
this.BtnGetContact.Label = "联系客服\n";
this.BtnGetContact.Label = "联系客服\r\n";
this.BtnGetContact.Name = "BtnGetContact";
this.BtnGetContact.ShowImage = true;
this.BtnGetContact.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnGetContact_Click);
@ -134,7 +157,7 @@ namespace AIProofread
//
this.BtnUpdate.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.BtnUpdate.Image = global::AIProofread.Properties.Resources.icon_update;
this.BtnUpdate.Label = "版本更新\n";
this.BtnUpdate.Label = "版本更新\r\n";
this.BtnUpdate.Name = "BtnUpdate";
this.BtnUpdate.ShowImage = true;
this.BtnUpdate.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnUpdate_Click);
@ -143,7 +166,7 @@ namespace AIProofread
//
this.btnLogin.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.btnLogin.Image = global::AIProofread.Properties.Resources.icon_user;
this.btnLogin.Label = "用户登录\n";
this.btnLogin.Label = "用户登录\r\n";
this.btnLogin.Name = "btnLogin";
this.btnLogin.ShowImage = true;
this.btnLogin.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.btnLogin_Click);
@ -152,7 +175,7 @@ namespace AIProofread
//
this.btnLogout.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.btnLogout.Image = global::AIProofread.Properties.Resources.icon_logout;
this.btnLogout.Label = "退出登录\n";
this.btnLogout.Label = "退出登录\r\n";
this.btnLogout.Name = "btnLogout";
this.btnLogout.ShowImage = true;
this.btnLogout.Visible = false;
@ -180,17 +203,33 @@ namespace AIProofread
//
this.ButtonSaveCache.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.ButtonSaveCache.Image = global::AIProofread.Properties.Resources.icon_save;
this.ButtonSaveCache.Label = "手动保存数据";
this.ButtonSaveCache.Label = "暂存文件\r\n";
this.ButtonSaveCache.Name = "ButtonSaveCache";
this.ButtonSaveCache.ShowImage = true;
this.ButtonSaveCache.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.ButtonSaveCache_Click);
//
// ButtonLoadCache
//
this.ButtonLoadCache.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.ButtonLoadCache.Image = global::AIProofread.Properties.Resources.icon_refresh;
this.ButtonLoadCache.Label = "追踪历史数据";
this.ButtonLoadCache.Image = global::AIProofread.Properties.Resources.icon_history;
this.ButtonLoadCache.Label = "加载文件\r\n";
this.ButtonLoadCache.Name = "ButtonLoadCache";
this.ButtonLoadCache.ShowImage = true;
this.ButtonLoadCache.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.ButtonLoadCache_Click);
//
// group2
//
this.group2.Items.Add(this.BtnShowPanel);
this.group2.Name = "group2";
//
// BtnShowPanel
//
this.BtnShowPanel.ControlSize = Microsoft.Office.Core.RibbonControlSize.RibbonControlSizeLarge;
this.BtnShowPanel.Image = global::AIProofread.Properties.Resources.icon_panel;
this.BtnShowPanel.Label = "显示面板\r\n";
this.BtnShowPanel.Name = "BtnShowPanel";
this.BtnShowPanel.ShowImage = true;
this.BtnShowPanel.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnShowPanel_Click);
//
// grpDebug
//
@ -198,6 +237,11 @@ namespace AIProofread
this.grpDebug.Items.Add(this.btnHidePane);
this.grpDebug.Items.Add(this.BtnOpenLog);
this.grpDebug.Items.Add(this.button1);
this.grpDebug.Items.Add(this.BtnOpenLogger);
this.grpDebug.Items.Add(this.BtnTest);
this.grpDebug.Items.Add(this.BtnOpenAppDir);
this.grpDebug.Items.Add(this.BtnShowVersion);
this.grpDebug.Items.Add(this.dropDown1);
this.grpDebug.Label = "开发调试";
this.grpDebug.Name = "grpDebug";
this.grpDebug.Visible = false;
@ -226,6 +270,41 @@ namespace AIProofread
this.button1.Name = "button1";
this.button1.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.button1_Click);
//
// BtnOpenLogger
//
this.BtnOpenLogger.Label = "打开日志窗口";
this.BtnOpenLogger.Name = "BtnOpenLogger";
this.BtnOpenLogger.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnOpenLogger_Click);
//
// BtnTest
//
this.BtnTest.Label = "打开dialog";
this.BtnTest.Name = "BtnTest";
this.BtnTest.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnTest_Click);
//
// BtnOpenAppDir
//
this.BtnOpenAppDir.Label = "打开插件目录";
this.BtnOpenAppDir.Name = "BtnOpenAppDir";
this.BtnOpenAppDir.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnOpenAppDir_Click);
//
// BtnShowVersion
//
this.BtnShowVersion.Label = "版本查看";
this.BtnShowVersion.Name = "BtnShowVersion";
this.BtnShowVersion.Click += new Microsoft.Office.Tools.Ribbon.RibbonControlEventHandler(this.BtnShowVersion_Click);
//
// dropDown1
//
ribbonDropDownItemImpl1.Label = "开发";
ribbonDropDownItemImpl2.Label = "测试";
ribbonDropDownItemImpl3.Label = "生产";
this.dropDown1.Items.Add(ribbonDropDownItemImpl1);
this.dropDown1.Items.Add(ribbonDropDownItemImpl2);
this.dropDown1.Items.Add(ribbonDropDownItemImpl3);
this.dropDown1.Label = "环境";
this.dropDown1.Name = "dropDown1";
//
// Ribbon1
//
this.Name = "Ribbon1";
@ -238,6 +317,8 @@ namespace AIProofread
this.group1.PerformLayout();
this.Group.ResumeLayout(false);
this.Group.PerformLayout();
this.group2.ResumeLayout(false);
this.group2.PerformLayout();
this.grpDebug.ResumeLayout(false);
this.grpDebug.PerformLayout();
this.ResumeLayout(false);
@ -266,6 +347,14 @@ namespace AIProofread
internal Microsoft.Office.Tools.Ribbon.RibbonGroup Group;
internal Microsoft.Office.Tools.Ribbon.RibbonButton ButtonSaveCache;
internal Microsoft.Office.Tools.Ribbon.RibbonButton ButtonLoadCache;
internal Microsoft.Office.Tools.Ribbon.RibbonButton BtnOpenLogger;
internal Microsoft.Office.Tools.Ribbon.RibbonButton BtnTest;
internal Microsoft.Office.Tools.Ribbon.RibbonButton BtnOpenAppDir;
internal Microsoft.Office.Tools.Ribbon.RibbonGroup group2;
internal Microsoft.Office.Tools.Ribbon.RibbonButton BtnShowPanel;
internal Microsoft.Office.Tools.Ribbon.RibbonButton BtnExportProofreadResult;
internal Microsoft.Office.Tools.Ribbon.RibbonButton BtnShowVersion;
internal Microsoft.Office.Tools.Ribbon.RibbonDropDown dropDown1;
}
partial class ThisRibbonCollection

View File

@ -3,13 +3,8 @@ 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;
@ -21,6 +16,7 @@ namespace AIProofread
public partial class Ribbon1
{
private bool IS_LOGIN = false;
private static bool IS_WPS = false;
private void Ribbon1_Load(object sender, RibbonUIEventArgs e)
{
@ -42,8 +38,43 @@ namespace AIProofread
}
}
public void SetCommonBtnStatus(bool status)
{
BtnProofreadAll.Enabled = status;
btnClear.Enabled = status;
btnOpenLexicon.Enabled = status;
btnSetting.Enabled = status;
BtnUpdate.Enabled = status;
btnLogin.Enabled = status;
btnLogout.Enabled = status;
ButtonLoadCache.Enabled = status;
ButtonSaveCache.Enabled = status;
//BtnShowPanel.Enabled = status;
BtnExportProofreadResult.Enabled = status;
}
public void SetBtnStatus(string key, bool status)
{
if (key == "proofread-status")
{
SetCommonBtnStatus(status);
}
else if (key == "view-panel")
{
BtnShowPanel.Enabled = status;
}
else if (key == "disable-by-upgrade")
{
SetCommonBtnStatus(status);
BtnShowPanel.Enabled = status;
}
}
/// <summary>
/// 初始化WPS相关功能(图标)
/// </summary>
public void InitWPS()
{
IS_WPS = true;
BtnProofreadAll.Image = AIProofread.Properties.Resources.icon_proofread_wps;
btnClear.Image = AIProofread.Properties.Resources.icon_clear_wps;
btnOpenLexicon.Image = AIProofread.Properties.Resources.icon_book_wps;
@ -55,13 +86,18 @@ namespace AIProofread
// 缓存相关
ButtonLoadCache.Image = AIProofread.Properties.Resources.icon_refresh_wps;
ButtonSaveCache.Image = AIProofread.Properties.Resources.icon_save_wps;
// 显示面板
BtnShowPanel.Image = AIProofread.Properties.Resources.icon_panel_wps;
// 导出校对结果
BtnExportProofreadResult.Image = AIProofread.Properties.Resources.icon_export_wps;
}
public void ProcessLoginInfo(Userinfo userinfo)
{
if (userinfo == null) return;
// 登录状态
IS_LOGIN = true;
// 切换登录状态
ToggleLogin();
LblNickname.Label = userinfo.nickname;
LblDate.Label = userinfo.expiration;
@ -69,13 +105,24 @@ namespace AIProofread
// 关闭所有登录窗口
foreach (var item in Globals.ThisAddIn.LoginFormList)
{
if (!item.IsDisposed)
try
{
item.Close();
if (!item.IsDisposed)
{
item.Close();
}
}
catch (Exception ex)
{
Logger.Log(this.Name, ex);
}
}
Globals.ThisAddIn.LoginFormList.Clear();
}
/// <summary>
/// 注销登录
/// </summary>
public void ProcessLogout()
{
IS_LOGIN = false;
@ -140,10 +187,10 @@ namespace AIProofread
{
//DocumentUtil.ClearProofreadMarks();
var result = MessageBox.Show("请确认是否清除此文档的所有校对标注?", "提示", MessageBoxButtons.OKCancel);
if(result == DialogResult.OK)
if (result == DialogResult.OK)
{
Bridge.bridge.clearAllProofreadMark(null);
Globals.ThisAddIn.SendMessageToWeb("clear-tips", null);
//Bridge.bridge.clearAllProofreadMark(null);
Globals.ThisAddIn.ClearAllProofreadMark();
}
}
@ -409,5 +456,58 @@ namespace AIProofread
{
Bridge.StartUpgradeProcess();
}
private void BtnOpenLogger_Click(object sender, RibbonControlEventArgs e)
{
// 判断日志窗口是否已经存在或者打开
if (Logger.LoggerForm == null || Logger.LoggerForm.IsDisposed)
{
// 创建日志窗口
Logger.LoggerForm = new FormLogger();
}
Logger.LoggerForm.Show();
}
private void BtnTest_Click(object sender, RibbonControlEventArgs e)
{
// 获取当前系统时间戳
//int time = (int)(DateTime.Now.Ticks / 10000000);
//BtnTest.Label = "测试按钮" + time;
var result = MessageBox.Show("Test", "xxx");
}
private void ButtonSaveCache_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.SendMessageToWeb("save-cache", "");
}
private void ButtonLoadCache_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.SendMessageToWeb("load-cache", "");
}
private void BtnShowPanel_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.SendMessageToWeb("show-panel", "");
}
private void BtnOpenAppDir_Click(object sender, RibbonControlEventArgs e)
{
// 打开日志目录
Process.Start(AppDomain.CurrentDomain.BaseDirectory);
}
private void BtnExportProofreadResult_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.SendMessageToWeb("export-result", "");
}
private void BtnShowVersion_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.SendMessageToWeb("show-version", "");
}
}
}

View File

@ -120,4 +120,19 @@
<metadata name="BtnProofreadAll.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="btnClear.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="btnOpenLexicon.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="btnSetting.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnGetContact.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="BtnUpdate.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View File

@ -1,16 +1,18 @@
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Threading;
using Microsoft.Office.Interop.Word;
using System.Linq;
using System.Windows.Forms;
using System.IO;
using AIProofread.Controls;
using UtilLib;
using AIProofread.Model;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
//using CustomTaskPane = Microsoft.Office.Core.CustomTaskPane;
using CustomTaskPane = Microsoft.Office.Tools.CustomTaskPane;
//using CustomTaskPane = Microsoft.Office.Tools.CustomTaskPane;
//using NPOI.SS.Formula.Functions;
namespace AIProofread
{
@ -38,34 +40,175 @@ namespace AIProofread
/// 工具栏
/// </summary>
public Ribbon1 ribbon;
/// <summary>
/// 当前word application
/// </summary>
public static Microsoft.Office.Interop.Word.Application CurrentWordApplication;
///// <summary>
///// 智能标记集合
///// </summary>
//internal SmartTagCollection VstoSmartTags;
/// <summary>
/// 所有文档信息
/// </summary>
public DocumentList documentList = new DocumentList();
/// <summary>
/// 当前文档信息
/// </summary>
public DocumentInfo ActiveDocument { get; set; }
public bool IsWPS { get; set; }
public List<FormLogin> LoginFormList = new List<FormLogin>();
public Dictionary<Document, CustomTaskPane> taskPanels = new Dictionary<Document, CustomTaskPane>();
public Dictionary<Document, bool> panelsVisibleStatus = new Dictionary<Document, bool>();
public Dictionary<Document, int> documentIdDics = new Dictionary<Document, int>();
//public override void BeginInit()
//{
// base.BeginInit();
// CurrentWordApplication = Application;
// CurrentWordApplication.DocumentChange += CurrentWordApplication_DocumentChange;
//}
/// <summary>
/// 当前文档面板
/// </summary>
public CustomTaskPane currentDocumentTaskPane;
/// <summary>
/// 所有文档信息
/// </summary>
public Dictionary<Document, DocumentInfo> documentList = new Dictionary<Document, DocumentInfo>();
/// <summary>
/// 当前文档信息
/// </summary>
public DocumentInfo CurrentDocument { get; set; }
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
try
{
AppInitialize();
Logger.Log("ThisAddIn_Startup IS_WPS --> " + IsWPS);
// 处理文档事件
Application.DocumentOpen += Application_DocumentOpen;
Application.DocumentBeforeClose += Application_DocumentBeforeClose;
private static readonly Dictionary<Document, Dictionary<int, ProofreadItem>> allMarks = new Dictionary<Document, Dictionary<int, ProofreadItem>>();
Application.WindowActivate += Application_WindowActivate;
//Application.WindowDeactivate += Application_WindowDeactivate;
Application.DocumentBeforeSave += Application_DocumentBeforeSave; ;
(Application as ApplicationEvents4_Event).NewDocument += Application_NewDocument;
Application.DocumentChange += Application_DocumentChange;
// 选区发生变化事件
this.Application.WindowSelectionChange += Application_WindowSelectionChange;
//CheckPluginUpgradeInfo();
}
catch (Exception ex1)
{
Logger.Log("Startup", ex1.ToString());
}
}
async void CheckPluginUpgradeInfo()
{
await System.Threading.Tasks.Task.Run(() =>
{
try
{
// 检测升级信息
Bridge.bridge.CheckPluginUpgrade();
}
catch (Exception ex)
{
Logger.Log("检测升级信息异常: " + ex.ToString());
}
});
}
private void Application_DocumentBeforeSave(Document originDocument, ref bool SaveAsUI, ref bool Cancel)
{
Logger.Log("DocumentSave", originDocument.Name + "\r\n");
if (CurrentWordApplication.Documents.Count == 0)
{
return;
}
if (ActiveDocument == null) return;
// TODO 完成缓存保存
}
//public DocumentInfo ActiveDocument()=> documentList.GetActiveDocument();
private void AppInitialize()
{
CurrentWordApplication = Application;
// 初始化配置
InitAppByConfig();
// 主线程
FmainThreadContext = SynchronizationContext.Current;
// 启动地址
applicationStartupPath = System.Windows.Forms.Application.StartupPath;
// 判断是否是WPS
if (applicationStartupPath.Contains("WPS"))
{
Config.IS_WPS = true;
IsWPS = true;
try
{
Globals.Ribbons.Ribbon1.InitWPS();
}
catch (Exception ex)
{
Logger.Log("Init WPS Error " + ex.Message);
}
}
}
private void InitAppByConfig()
{
try
{
if (File.Exists(Config.CONFIG_FILE))
{
string content = File.ReadAllText(Config.CONFIG_FILE);
Logger.Log("INIT", "Found app.json " + content);
if (content == null || content.Length == 0) return;
AppConfig config = JsonConvert.DeserializeObject<AppConfig>(content);
// 插件网址
if (!string.IsNullOrEmpty(config.AppUrl))
{
Config.WEB_PATH = config.AppUrl;
}
// 运行环境
if (!string.IsNullOrEmpty(config.Environment))
{
Config.APP_ENV = config.Environment == "dev" ? AppEnvironment.Dev : (
config.Environment == "test" ? AppEnvironment.Test : AppEnvironment.Prod
);
}
Config.RUN_IN_DEBUG = config.AppRunInDebug;
if (Config.APP_ENV != AppEnvironment.Prod && this.ribbon != null)
{
this.ribbon.ShowDebug();
}
}
}
catch (Exception) { }
}
private void Application_DocumentChange()
{
// 检测是否存在打开的文档
if (CurrentWordApplication.Documents.Count == 0)
{
return;
}
//var document = CurrentWordApplication.ActiveDocument;
// 设置当前文档
ActiveDocument = documentList.SetActiveDocument(CurrentWordApplication.ActiveDocument);
ActiveDocument.CheckBtnStatus();
Logger.Log("Application_DocumentChange -- " + ActiveDocument.fileName);
}
public void SetActiveDocument(Document doc)
{
ActiveDocument = documentList.SetActiveDocument(doc);
}
private void Application_WindowDeactivate(Document doc, Window Wn)
{
Logger.Log("Application_WindowDeactivate -- " + doc.FullName + " visible:");
//Logger.Log("Application_WindowDeactivate -- " + doc.FullName + " visible:");
//HidePanel(Doc);
// 处理wps直接资源管理器新开文档面板闪烁问题
//if (IsWPS) {
@ -73,164 +216,77 @@ namespace AIProofread
//}
}
/// <summary>
/// 激活文档
/// </summary>
/// <param name="activeDoc"></param>
/// <param name="Wn"></param>
private void Application_WindowActivate(Document activeDoc, Window Wn)
{
// 当前文档添加书签集合
if (!allMarks.ContainsKey(activeDoc))
{
allMarks[activeDoc] = new Dictionary<int, ProofreadItem>();
}
Logger.Log("Application_WindowActivate -- " + activeDoc.FullName);
//ShowPanel(Doc);
// 创建面板
if (!taskPanels.ContainsKey(activeDoc))
{
ShowPanel(activeDoc, false);
panelsVisibleStatus.Add(activeDoc, false);
}
// 设置当前面板为新创建的面板
this.currentDocumentTaskPane = taskPanels[activeDoc];
if (IsWPS)
{
HideOtherPanel(activeDoc);
}
if (panelsVisibleStatus.ContainsKey(activeDoc) && panelsVisibleStatus[activeDoc])
{
taskPanels[activeDoc].Visible = true;
}
ActiveDocument = documentList.SetActiveDocument(activeDoc);
Logger.Log("Application_WindowActivate -- " + ActiveDocument.fileName);
//// 当前文档添加书签集合
//if (!allMarks.ContainsKey(activeDoc))
//{
// allMarks[activeDoc] = new Dictionary<int, ProofreadItem>();
//}
////ShowPanel(Doc);
//// 创建面板
//if (!taskPanels.ContainsKey(activeDoc))
//{
// ShowPanel(activeDoc, false);
// panelsVisibleStatus.Add(activeDoc, false);
//}
//// 设置当前面板为新创建的面板
//this.currentDocumentTaskPane = taskPanels[activeDoc];
//if (IsWPS)
//{
// HideOtherPanel(activeDoc);
//}
//if (panelsVisibleStatus.ContainsKey(activeDoc) && panelsVisibleStatus[activeDoc])
//{
// taskPanels[activeDoc].Visible = true;
//}
}
/// <summary>
/// 关闭文档
/// </summary>
/// <param name="currentDoc"></param>
/// <param name="Cancel"></param>
private void Application_DocumentBeforeClose(Document currentDoc, ref bool Cancel)
{
Logger.Log("Application_DocumentBeforeClose -- " + currentDoc.FullName);
if (allMarks.ContainsKey(currentDoc))
{
allMarks.Remove(currentDoc);
}
Logger.Log("DocumentBeforeClose", currentDoc.FullName);
documentList.Remove(currentDoc);
//if (allMarks.ContainsKey(currentDoc))
//{
// allMarks.Remove(currentDoc);
//}
DisposePanel(currentDoc);
//DisposePanel(currentDoc);
}
public void ActiveCurrentDocumentMarks(Document document)
//public void ActiveCurrentDocumentMarks(Document document)
//{
// // 判断是否存在 没有的话初始化
// var currentDoc = document ?? Application.ActiveDocument ;
// if (!allMarks.ContainsKey(currentDoc))
// {
// allMarks[currentDoc] = new Dictionary<int, ProofreadItem>();
// }
// Bridge.marks = allMarks[currentDoc];
//}
private void Application_NewDocument(Document doc)
{
// 判断是否存在 没有的话初始化
var currentDoc = document ?? Application.ActiveDocument ;
if (!allMarks.ContainsKey(currentDoc))
{
allMarks[currentDoc] = new Dictionary<int, ProofreadItem>();
}
Bridge.marks = allMarks[currentDoc];
Logger.Log("NewDocument", doc.Name);
}
private void Application_NewDocument(Document Doc)
private void Application_DocumentOpen(Document doc)
{
Logger.Log("Application_NewDocument -- " + Doc.FullName);
ShowPanel(Doc);
Logger.Log("DocumentOpen", doc.Name);
}
private void Application_DocumentOpen(Document Doc)
{
Logger.Log("Application_DocumentOpen -- " + Doc.FullName);
ShowPanel(Doc);
}
void DisposePanel(Document doc)
{
if (panelsVisibleStatus.ContainsKey(doc))
{
panelsVisibleStatus.Remove(doc);
}
if (taskPanels.ContainsKey(doc))
{
var control = (ProofreadMainControl)taskPanels[doc].Control;
control.ResetWeb();
taskPanels[doc].Visible = false;
taskPanels[doc].Dispose();
taskPanels.Remove(doc);
}
}
void HideOtherPanel(Document doc)
{
if (taskPanels.ContainsKey(doc) && taskPanels[doc].Visible)
{
return;
}
// 隐藏其他的文档
foreach (var key in taskPanels.Keys)
{
// 记录面板原始状态
if (key != doc)
{
taskPanels[key].Visible = false;
}
}
}
void HidePanel(Document doc)
{
if (taskPanels.ContainsKey(doc))
{
taskPanels[doc].Visible = false;
}
}
private CustomTaskPane ShowPanel(Document doc, bool show)
{
if (Application.ActiveDocument == null) return null;
if (doc == null) doc = Application.ActiveDocument;
if (taskPanels.ContainsKey(doc))
{
return taskPanels[doc];
}
//proofreadPanel = new ProofreadMainControl();
var control = new ProofreadMainControl(doc, MinWidth);
if (MinWidth < 10)
{
MinWidth = 420 * control.LabelWidth() / 42;
}
var panel = Globals.ThisAddIn.CustomTaskPanes.Add(control, AddinName);
this.currentDocumentTaskPane = panel;
taskPanels.Add(doc, panel);
panel.Visible = false;
// 设置宽度
control.Width = MinWidth;
panel.Width = MinWidth;
// 监听尺寸变化 防止最小尺寸小于设置值
control.SizeChanged += Control_SizeChanged;
//new CustomTaskPaneHandler(control, MinWidth);
return panel;
}
/// <summary>
/// word创建面板
/// </summary>
private CustomTaskPane ShowPanel(Document doc)
{
return ShowPanel(doc, !IsWPS);
}
/// <summary>
/// 添加变量控制重复调用
/// </summary>
private bool isResizing = false;
private void Control_SizeChanged(object sender, EventArgs e)
{
if (isResizing) return;
if (currentDocumentTaskPane != null && currentDocumentTaskPane.Visible && currentDocumentTaskPane.Width < MinWidth)
{
isResizing = true;
SendKeys.Send("{ESC}");
currentDocumentTaskPane.Width = MinWidth;
isResizing = false;
}
}
public int GetMinWidth()
{
@ -252,97 +308,13 @@ namespace AIProofread
// }
//}
private void InitAppByConfig()
{
try
{
if (File.Exists(Config.CONFIG_FILE))
{
string content = File.ReadAllText(Config.CONFIG_FILE);
Logger.Log("Found app.json " + content);
if (content == null || content.Length == 0) return;
AppConfig config = JsonConvert.DeserializeObject<AppConfig>(content);
// 插件网址
if (!string.IsNullOrEmpty(config.AppUrl))
{
Config.WEB_PATH = config.AppUrl;
}
// 运行环境
if (!string.IsNullOrEmpty(config.Environment))
{
Config.APP_ENV = config.Environment == "dev" ? AppEnvironment.Dev : (
config.Environment == "test" ? AppEnvironment.Test : AppEnvironment.Prod
);
}
if (Config.APP_ENV != AppEnvironment.Prod && this.ribbon != null)
{
this.ribbon.ShowDebug();
}
}
}
catch (Exception) { }
}
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
try
{
InitAppByConfig();
FmainThreadContext = SynchronizationContext.Current;
// 启动地址
applicationStartupPath = System.Windows.Forms.Application.StartupPath;
if (applicationStartupPath.Contains("WPS"))
{
IsWPS = true;
Config.IS_WPS = true;
try
{
Globals.Ribbons.Ribbon1.InitWPS();
}
catch (Exception ex)
{
Logger.Log("Init WPS Error " + ex.Message);
}
}
// 处理文档事件
Application.DocumentOpen += Application_DocumentOpen;
Application.DocumentBeforeClose += Application_DocumentBeforeClose;
Application.WindowActivate += Application_WindowActivate;
Application.WindowDeactivate += Application_WindowDeactivate;
(Application as ApplicationEvents4_Event).NewDocument += Application_NewDocument;
//Application.DocumentChange +=
// 选区发生变化事件
this.Application.WindowSelectionChange += Application_WindowSelectionChange;
// 检测升级信息
Bridge.bridge.InitPluginUpgrade();
try
{
if (Application.Documents.Count > 0 && Application.ActiveDocument != null)
{
// 默认直接打开文档 就直接创建panel
ShowPanel(Application.ActiveDocument, false);
}
}
catch (Exception ex2)
{
Logger.Log("加载默认文档失败: " + ex2.ToString());
}
}
catch (Exception ex1)
{
Logger.Log("Init Error " + ex1.ToString());
}
}
private void Application_WindowSelectionChange(Selection s)
{
if (s.Bookmarks != null)
{
if (s.Range.Start == s.Range.End) // 说明是点击呀
{
var count = s.Bookmarks.Count;
//var count = s.Bookmarks.Count;
if (s.Bookmarks.Count >= 1) // 只有这一个
{
foreach (Bookmark item in s.Bookmarks)
@ -352,13 +324,15 @@ namespace AIProofread
{
// 只选择第一个书签
// TODO: 优化
//Bridge.bridge.SelectMarkById(proofreadId, 0);
ActiveDocument?.SelectMarkById(proofreadId, true);
return;
}
}
}
}
}
Bridge.bridge.SelectMarkById(-1,0);
//Bridge.bridge.SelectMarkById(-1, 0);
}
public int MyProperty { get; set; }
@ -366,46 +340,21 @@ namespace AIProofread
public void SendMessageToWeb(string msg, object data)
{
// 先显示panel
var panel = this.ShowPanel(Application.ActiveDocument, true);
SendMessageToWeb(panel.Control, msg, data);
}
public void SendMessageToWeb(UserControl panelControl, string msg, object data)
{
var json = JsonConvert.SerializeObject(new WebMessage(msg, data));
var control = (ProofreadMainControl)panelControl;
try
{
if (control.web.CoreWebView2 == null)
{
Thread.Sleep(500);
}
control.web.CoreWebView2.PostWebMessageAsJson(json);
}
catch (Exception ex)
{
Logger.Log("send message to web error \n" + ex.Message + "\n" + msg + data.ToString());
}
//var panel = this.ShowPanel(Application.ActiveDocument, true);
//SendMessageToWeb(panel.Control, msg, data);
ActiveDocument?.SendMessageToWeb(msg, data);
}
// 显示面板
public void ShowPanel()
{
this.currentDocumentTaskPane.Visible = true;
if (panelsVisibleStatus.ContainsKey(Application.ActiveDocument))
{
panelsVisibleStatus[Application.ActiveDocument] = true;
}
ActiveDocument?.ShowPane();
}
// 隐藏面板
public void HidePanel()
{
this.currentDocumentTaskPane.Visible = false;
if (panelsVisibleStatus.ContainsKey(Application.ActiveDocument))
{
panelsVisibleStatus[Application.ActiveDocument] = false;
}
ActiveDocument?.HidePane();
}
/// <summary>
@ -413,44 +362,102 @@ namespace AIProofread
/// </summary>
public void HideAllPanel()
{
foreach (var item in taskPanels)
{
item.Value.Visible = false;
}
this.documentList.HideAllPane();
}
/// <summary>
/// 显示登录窗口
/// </summary>
/// <param name="action"></param>
public void ShowLoginForm(string action)
{
FormLogin frm = new FormLogin(action);
LoginFormList.Add(frm);
frm.Show();
// 关闭之前的窗口
//if(LoginFormList.Count > 0){
// LoginFormList.ForEach(f => f.Close());
//}
//LoginFormList.Add(frm);
ActiveDocument?.ShowLogin(action);
}
void ClearPanels()
{
taskPanels.Values.ToList().ForEach(p =>
{
try
{
p.Dispose();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
Logger.Log(ex.Message + "\n" + ex.StackTrace);
}
});
taskPanels.Clear();
}
/// <summary>
/// 清理所有面板
/// </summary>
//void ClearPanels()
//{
// taskPanels.Values.ToList().ForEach(p =>
// {
// try
// {
// p.Dispose();
// }
// catch (Exception ex)
// {
// Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
// Logger.Log(ex.Message + "\n" + ex.StackTrace);
// }
// });
// taskPanels.Clear();
//}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
// PanelModule.DisposeCTP();
//this.proofreadPanel.Dispose();
ClearPanels();
Logger.Log("shutdown");
documentList.Clear();
}
public void SyncLogout()
{
ribbon.ProcessLogout();
//taskPanels.Values.ToList().ForEach(p =>
//{
// try
// {
// // 同步登录失败信息
// SendMessageToWeb(p.Control, "async-logout", null);
// }
// catch (Exception ex)
// {
// Logger.Log("async-logout:", ex);
// }
//});
}
public void SetDocumentId(Document document, int id)
{
var doc = documentList.Get(document);
if (doc != null) doc.Id = id;
}
public DocumentInfo GetDocumentById(int id)
{
return documentList.GetById(id);
}
/// <summary>
/// 清除所有标记
/// </summary>
public void ClearAllProofreadMark()
{
ActiveDocument?.ClearAllProofreadMark();
Globals.ThisAddIn.SendMessageToWeb("clear-tips", null);
}
//public string LoadCacheByPath()
//{
//}
//public void SaveCache(string cache)
//{
//}
#region VSTO generated code
/// <summary>
@ -463,22 +470,9 @@ namespace AIProofread
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
public void SyncLogout()
public void InitProofreadCacheList(System.Collections.Generic.List<CorrectContext> list)
{
ribbon.ProcessLogout();
taskPanels.Values.ToList().ForEach(p =>
{
try
{
// 同步登录失败信息
SendMessageToWeb(p.Control, "async-logout", null);
}
catch (Exception ex)
{
Logger.Log("async-logout:", ex);
}
});
ActiveDocument?.InitProofreadCache(list);
}
#endregion

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace AIProofread.Util
{
public class User32Util
{
[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT rect);
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
// 引入 User32.dll 中的 SetParent 方法
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
}

View File

@ -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
{
@ -173,7 +177,7 @@ namespace AIProofread
/// <param name="document"></param>
/// <param name="range"></param>
/// <returns></returns>
public static Range FindRange(CorrectItem correct, CorrectContext sentense,ref int prevOffset, Microsoft.Office.Interop.Word.Document document, Range range)
public static Range FindRange(CorrectItem correct, CorrectContext sentense, ref int prevOffset, Microsoft.Office.Interop.Word.Document document, Range range)
{
var paragraphText = range.Text;
@ -194,7 +198,7 @@ namespace AIProofread
End = range.Start + offset + wordEnd;
Start = range.Start + offset + wordStart;
// 直接找到
var findRange = activeDocument.Range(ref Start,ref End);
var findRange = activeDocument.Range(ref Start, ref End);
// 判断对应选区是否是要找的文本
if (findRange.Text == findText)
{
@ -291,7 +295,47 @@ namespace AIProofread
}
public static Bookmark FindBookMarkByCorrect(CorrectItem correct)
{
try
{
var document = Globals.ThisAddIn.ActiveDocument.CurrentDocument;
var marks = document.Bookmarks;
var markName = Config.BuildBookmarkName(correct.Id);
if (!document.Bookmarks.Exists(markName)) return null;
ControlCollection controls = Globals.Factory.GetVstoObject(document).Controls;
//return controls[markName] as Bookmark;
//var obj = controls[markName];
var bookmark = marks[markName];
var start = bookmark.Range.Start;
var end = bookmark.Range.End;
// 删除原有书签
controls.Remove(markName);
return controls.AddBookmark(document.Range(start, end), markName);
}
catch (Exception ex)
{
Logger.Log(ex);
}
return null;
//if(bookmark == null)
//{
// foreach (var m in marks)
// {
// var mark = m as Bookmark;
// var name = mark.Name;
// var tag = mark.Tag?.ToString();
// if(tag == markName || name == markName)
// {
// return mark;
// }
// }
//}
//return bookmark as Bookmark;
}
public static Bookmark FindRangeAndCreateBookmark(CorrectItem correct, CorrectContext sentense, Microsoft.Office.Interop.Word.Document document, ref int prevOffset)
{
@ -321,6 +365,7 @@ namespace AIProofread
// 更新查找的结束位置
//prevOffset = findRange.End - paragraphStart;
bookmark = controls.AddBookmark(findRange, markName);
bookmark.Tag = "ai_proofread";
}
}
@ -338,12 +383,22 @@ namespace AIProofread
var paraStart = paraRange.Start;
// 定位句子的其实位置
var offset = paraStart + c.SentenceOffset;
//var cutLength = Math.Min(c.InsertLen, paraText.Length - offset);
var sentence = paraText.Substring(c.SentenceOffset, c.InsertLength);
if (sentence == c.Insert)
{ // 比对原始内容与校对原文是否一致
var range = document.Range(offset + item.Start, offset + item.End);
//var offset = paraStart + c.SentenceOffset;
////var cutLength = Math.Min(c.InsertLen, paraText.Length - offset);
/// TODO 目前接口没有返回 句子相关数据 直接获取
var sentence = paraRange.Sentences[c.SentenceNumber]; //paraText.Substring(c.SentenceOffset, c.InsertLength);
c.SentenceOffset = sentence.Start;
var offset = c.SentenceOffset;
c.Insert = sentence.Text;
if (sentence.Text == c.Insert)
{
if (item.Tag == "i")
{
return document.Range(offset + item.Start, offset + item.Start);
}
// 比对原始内容与校对原文是否一致
var range = document.Range(offset + item.Start, offset + item.End + 1);
//
if (range.Text == item.Origin) return range;
}
@ -371,7 +426,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);
}
}
@ -398,7 +453,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; }
}
// 直接定位查找
@ -409,5 +464,153 @@ 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);
if(it.Tag == "r") {
var suggest = it.Text;
if(it.Type == "sensitive")
{
suggest += "(敏感词)";
}
else if (it.Type == "blacklist")
{
suggest += "(敏感词)";
}
else if (!string.IsNullOrEmpty(it.Addition))
{
suggest += $"({it.Addition})";
}
row.CreateCell(5).SetCellValue(suggest);
}
else if(it.Tag == "i")
{
row.CreateCell(5).SetCellValue("新增");
}
else if (it.Tag == "e")
{
row.CreateCell(5).SetCellValue("删除");
}
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 "未处理";
}
}
}

View File

@ -80,8 +80,14 @@ namespace AIProofread.core
}
public static void DisabledProofreadItem(List<int> proofreadItemIdList)
{
if (proofreadItemIdList.Count == 0) return;
Globals.ThisAddIn.SendMessageToWeb(MessageActionEnum.DisableProofreadItem.Action, proofreadItemIdList);
}
public static void DisabledProofreadItem(int proofreadItemId)
{
DisabledProofreadItem(new List<int>() { proofreadItemId });
}
}
}

View File

@ -17,7 +17,7 @@ namespace AIProofread
{
if (ctp == null)
{
uc = new ProofreadMainControl(null,450);
uc = new ProofreadMainControl();
ctp = Globals.ThisAddIn.CustomTaskPanes.Add(control: uc, title: "AI校对王");
ctp.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
}

View File

@ -1 +1 @@
11c03afee37eea7e40c8b52f8e997c1261df45d7ed4e6445471b049c699b20a7
73697d8cfbb569cc987afc71aa3dff1fa36374eacaf0a7c7b55871ef5023996c

View File

@ -206,3 +206,8 @@ C:\Users\yaclt\source\repos\repos\AIProofread\AIProofread\obj\Debug\AIProofread.
C:\Users\yaclt\source\repos\repos\AIProofread\AIProofread\obj\Debug\AIProofr.8811D769.Up2Date
C:\Users\yaclt\source\repos\repos\AIProofread\AIProofread\obj\Debug\AIProofread.dll
C:\Users\yaclt\source\repos\repos\AIProofread\AIProofread\obj\Debug\AIProofread.pdb
C:\Users\yaclt\source\repos\repos\AIProofread\AIProofread\obj\Debug\AIProofread.Controls.FormLogger.resources
C:\Users\yaclt\source\repos\repos\AIProofread\AIProofread\obj\Debug\AIProofread.Controls.FormMessage.resources
C:\Users\yaclt\source\repos\repos\AIProofread\AIProofread\obj\Debug\AIProofread.Controls.FormDialog.resources
C:\Users\yaclt\source\repos\repos\AIProofread\AIProofread\obj\Debug\AIProofread.Controls.FormWebView.resources
C:\Users\yaclt\source\repos\repos\AIProofread\AIProofread\obj\Debug\AIProofread.Controls.FormMask.resources

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
</configuration>

40
ai-proofread-client/Form1.Designer.cs generated Normal file
View File

@ -0,0 +1,40 @@
namespace ai_proofread_client
{
partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -0,0 +1,20 @@
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 ai_proofread_client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,34 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace ai_proofread_client
{
internal static class Program
{
[DllImport("kernel32.dll")]
public static extern bool AllocConsole();
[DllImport("kernel32.dll")]
static extern bool FreeConsole();
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
// 允许调用控制台输出
AllocConsole();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());
Console.WriteLine("xxx-->0");
Debug.WriteLine("xxx-->1");
Console.WriteLine(string.Join("\n",args));
Console.ReadLine();
// 释放
FreeConsole();
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("ai-proofread-client")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ai-proofread-client")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("48c0b207-150a-40b7-9a25-ecf9218ff86f")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本: 4.0.30319.42000
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace ai_proofread_client.Properties
{
/// <summary>
/// 强类型资源类,用于查找本地化字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// 返回此类使用的缓存 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ai_proofread_client.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ai_proofread_client.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{48C0B207-150A-40B7-9A25-ECF9218FF86F}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>ai_proofread_client</RootNamespace>
<AssemblyName>ai-proofread-client</AssemblyName>
<TargetFrameworkVersion>v4.6.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -72,10 +72,25 @@ namespace updater
string runningApp = CheckHostAppRunning();
if (!string.IsNullOrEmpty(runningApp))
{
MessageBox.Show(string.Format("检测到{0}正在运行中,请关闭{0}后继续执行更新操作",runningApp));
ButtonProcess.Visible = true;
ButtonProcess.Text = "继续更新";
return;
var result = MessageBox.Show(string.Format("检测到{0}正在运行中,是否强制关闭并继续执行更新操作",runningApp));
if(result != DialogResult.OK)
{
ButtonProcess.Visible = true;
ButtonProcess.Text = "继续更新";
return;
}
try
{
OfficeKiller.KillWPSProcess();
OfficeKiller.KillWordProcess();
}
catch (Exception)
{
MessageBox.Show("强制关闭失败,请手动关闭后重新执行更新操作");
ButtonProcess.Visible = true;
ButtonProcess.Text = "继续更新";
return;
}
}
ButtonProcess.Visible = false;
progressBar1.Visible = true;

View File

@ -4,7 +4,7 @@ namespace updater
{
public class OfficeKiller
{
public void KillWordProcess()
public static void KillWordProcess()
{
Process[] processesByName = Process.GetProcessesByName("WINWORD");
foreach (Process obj in processesByName)
@ -15,7 +15,7 @@ namespace updater
}
}
public void KillExcelProcess()
public static void KillExcelProcess()
{
Process[] processesByName = Process.GetProcessesByName("EXCEL");
foreach (Process obj in processesByName)
@ -25,7 +25,7 @@ namespace updater
}
}
public void KillWPSProcess()
public static void KillWPSProcess()
{
Process[] processesByName = Process.GetProcessesByName("wps");
foreach (Process process in processesByName)

View File

@ -16,14 +16,21 @@ namespace UtilLib
/// </summary>
[JsonProperty("new_text")]
public string NewText { get; set; }
/// <summary>
/// 句子原始文本长度
/// </summary>
[JsonProperty("insert_len")]
public int InsertLength { get; set; }
//[JsonProperty("insert_len")]
//public int InsertLength { get; set; }
/// <summary>
/// 校对位移(相对当前句子)
/// </summary>
[JsonProperty("start_num")]
public int Offset { get; set; }
public int Paragraph_offset { get; set; }
//public int Paragraph_offset { get; set; }
/// <summary>
/// 句子所在文档的段落数(从1开始)
/// </summary>
@ -31,13 +38,21 @@ namespace UtilLib
public int ParagraphNumber { get; set; }
/// <summary>
/// 句子在段落中的其实位置
/// 句子在段落中的起始位置
/// </summary>
[JsonProperty("sentence_offset")]
public int SentenceOffset { get; set; }
/// <summary>
/// 当前句子在段落的序号
/// </summary>
[JsonProperty("sentence_num")]
public int SentenceNumber { get; set; }
/// <summary>
/// 当前句子的校对列表项
/// </summary>
[JsonProperty("diffs")]
public List<CorrectItem> CorrectItems { get; set; }
}
}

View File

@ -5,7 +5,7 @@ namespace UtilLib
public class CorrectItem
{
/// <summary>
/// 校对类别()
/// 校对类别(r 替换 d 删除 i 插入新增)
/// </summary>
public string Tag { get; set; }
/// <summary>
@ -29,13 +29,13 @@ namespace UtilLib
/// </summary>
public int Id { get; set; }
/// <summary>
/// 校对项索引
/// 标识类型index字符型数字
/// </summary>
public int idx { get; set; }
public int Index { get; set; }
/// <summary>
/// 校对所属分类
/// 标识类型(校对所属分类)
/// </summary>
public int Type { get; set; }
public string Type { get; set; }
/// <summary>
/// 校对状态
/// </summary>
@ -45,5 +45,9 @@ namespace UtilLib
/// 校对项颜色
/// </summary>
public string Color { get; set; }
/// <summary>
/// 标识类型(校对所属分类)
/// </summary>
public string Addition { get; set; }
}
}