CrazyIter_Bin 1 éve
szülő
commit
371a42997d

+ 44 - 5
HTEXMark/HTEXMark.csproj

@@ -26,16 +26,39 @@
     <NoStandardLibraries>false</NoStandardLibraries>
     <RootNamespace>HTEXMark</RootNamespace>
     <AssemblyName>HTEXMark</AssemblyName>
-    <LoadBehavior>3</LoadBehavior>
     <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
     <DefineConstants>VSTO40</DefineConstants>
+    <IsWebBootstrapper>False</IsWebBootstrapper>
     <BootstrapperEnabled>true</BootstrapperEnabled>
-    <BootstrapperComponentsLocation>HomeSite</BootstrapperComponentsLocation>
+    <PublishUrl>publish\</PublishUrl>
+    <InstallUrl />
+    <TargetCulture>zh-chs</TargetCulture>
+    <ApplicationVersion>1.0.0.2</ApplicationVersion>
+    <AutoIncrementApplicationRevision>true</AutoIncrementApplicationRevision>
+    <UpdateEnabled>true</UpdateEnabled>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>days</UpdateIntervalUnits>
+    <ProductName>HTEXMark</ProductName>
+    <PublisherName />
+    <SupportUrl />
+    <FriendlyName>HTEXMark</FriendlyName>
+    <OfficeApplicationDescription />
+    <LoadBehavior>3</LoadBehavior>
   </PropertyGroup>
   <ItemGroup>
+    <BootstrapperPackage Include=".NETFramework,Version=v4.8">
+      <Visible>False</Visible>
+      <ProductName>Microsoft .NET Framework 4.8 %28x86 和 x64%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
     <BootstrapperPackage Include="Microsoft.VSTORuntime.4.0">
       <Visible>False</Visible>
-      <ProductName>Microsoft Visual Studio 2010 Tools for Office Runtime %28x86 and x64%29</ProductName>
+      <ProductName>Microsoft Visual Studio 2010 Tools for Office Runtime %28x86  x64%29</ProductName>
       <Install>true</Install>
     </BootstrapperPackage>
   </ItemGroup>
@@ -115,6 +138,7 @@
     <Reference Include="Microsoft.IdentityModel.Tokens, Version=7.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <HintPath>F:\NuGet\packages\Microsoft.IdentityModel.Tokens.7.2.0\lib\net472\Microsoft.IdentityModel.Tokens.dll</HintPath>
     </Reference>
+    <Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL" />
     <Reference Include="System" />
     <Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
       <HintPath>F:\NuGet\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
@@ -251,6 +275,9 @@
     can be found.
   -->
   <ItemGroup>
+    <Compile Include="KnowledgeUserControl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
     <Compile Include="LangResource.Designer.cs">
       <AutoGen>True</AutoGen>
       <DesignTime>True</DesignTime>
@@ -266,6 +293,9 @@
     <Compile Include="Properties\AssemblyInfo.cs">
       <SubType>Code</SubType>
     </Compile>
+    <EmbeddedResource Include="KnowledgeUserControl.resx">
+      <DependentUpon>KnowledgeUserControl.cs</DependentUpon>
+    </EmbeddedResource>
     <EmbeddedResource Include="LangResource.resx">
       <Generator>PublicResXFileCodeGenerator</Generator>
       <LastGenOutput>LangResource.Designer.cs</LastGenOutput>
@@ -343,6 +373,15 @@
     <Content Include="Images\问答题.png" />
     <Content Include="Images\难度.png" />
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HTEXLabel\HTEXLabel.csproj">
+      <Project>{D7EEB2A3-1CD2-448C-9E21-C24BA5C875F9}</Project>
+      <Name>HTEXLabel</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Resources\" />
+  </ItemGroup>
   <PropertyGroup>
     <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
     <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
@@ -365,8 +404,8 @@
     <VisualStudio>
       <FlavorProperties GUID="{BAA0C2D2-18E2-41B9-852F-F413020CAA33}">
         <ProjectProperties HostName="Word" HostPackage="{29A7B9D7-A7F1-4328-8EF0-6B2D1A56B2C1}" OfficeVersion="15.0" VstxVersion="4.0" ApplicationType="Word" Language="cs" TemplatesPath="" DebugInfoExeName="#Software\Microsoft\Office\16.0\Word\InstallRoot\Path#WINWORD.EXE" DebugInfoCommandLine="/x" AddItemTemplatesGuid="{51063C3A-E220-4D12-8922-BDA915ACD783}" />
-        <Host Name="Word" GeneratedCodeNamespace="HTEXMark" IconIndex="0">
-          <HostItem Name="ThisAddIn" Code="ThisAddIn.cs" CanonicalName="AddIn" CanActivate="false" IconIndex="1" Blueprint="ThisAddIn.Designer.xml" GeneratedCode="ThisAddIn.Designer.cs" />
+        <Host Name="Word" GeneratedCodeNamespace="HTEXMark" PublishedHash="69C324AB27932AA2FBF2B7EA72250886FF164DE6" IconIndex="0">
+          <HostItem Name="ThisAddIn" Code="ThisAddIn.cs" CanonicalName="AddIn" CanActivate="false" IconIndex="1" Blueprint="ThisAddIn.Designer.xml" GeneratedCode="ThisAddIn.Designer.cs" PublishedHash="AA0118D4DD3E7D57827217845DDCCFD42750B25B" />
         </Host>
       </FlavorProperties>
     </VisualStudio>

+ 40 - 0
HTEXMark/KnowledgeUserControl.cs

@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using static HTEXMark.QRCodeForm;
+
+namespace HTEXMark
+{
+    public class KnowledgeUserControl : UserControl
+    {
+        public KnowledgeUserControl()
+        {
+            
+           
+        }
+        public void InitializeTreeView(System.Windows.Forms.ListBox knowledgeListBox,List<Block> block)
+        {
+          
+            foreach (var item in block)
+            {
+                // 将 TreeView 添加到 UserControl1 的 Controls 集合中
+                if (item.points.Count()>0) {
+                   
+                  
+                    knowledgeListBox.Name=item.name;
+                    foreach (var point in item.points)
+                    {
+                      
+                        this.BeginInvoke(new Action(() => { knowledgeListBox.Items.Add(point); }));
+                    }
+                }
+            }
+            
+        }
+    }
+}

+ 120 - 0
HTEXMark/KnowledgeUserControl.resx

@@ -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>

+ 4 - 0
HTEXMark/MarkLanguage.cs

@@ -43,5 +43,9 @@ namespace HTEXMark
         public string user { get; set; }
         public string qrcode_title {  get; set; }
         public string unlogin { get; set; }
+        public string paneTitle { get; set; }
+        public string schoolDropDown { get; set; }
+        public string subjectDropDown { get; set; }
+        public string pointMsgShow { get; set; }
     }
 }

+ 202 - 23
HTEXMark/MarkRibbon.cs

@@ -1,4 +1,5 @@
 using Microsoft.Office.Core;
+using Microsoft.Office.Interop.Word;
 using Microsoft.Office.Tools.Ribbon;
 using Microsoft.Office.Tools.Word;
 using System;
@@ -6,29 +7,26 @@ using System.Collections;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using System.Net.Http;
 using System.Reflection;
 using System.Text;
 using System.Text.Json;
+using System.Threading.Tasks;
 using System.Windows.Forms;
+using static HTEXMark.QRCodeForm;
+using static ZXing.QrCode.Internal.Version;
+using Task = System.Threading.Tasks.Task;
 namespace HTEXMark
 {
     public partial class MarkRibbon
     {
         public static MarkLanguage lang = null;
+        public   KnowledgeUserControl knowledgeUserControl;
+        public  System.Windows.Forms.ListBox knowledgeListBox;
+        private HttpClient httpClient;
+        public Microsoft.Office.Tools.CustomTaskPane customTaskPane;
         private void MarkRibbon_Load(object sender, RibbonUIEventArgs e)
         {
-
-
-            List<string> strs = new List<string>() { "1", "2", "3" };
-
-            foreach (var x in strs)
-            {
-                var dropDownItem = Factory.CreateRibbonDropDownItem();
-                dropDownItem.Label=x;
-                dropDownItem.Tag=x;
-                schoolDropDown.Items.Add(dropDownItem);
-            }
-            var wordApp = Globals.ThisAddIn.Application;
             // 获取 Office 应用程序的语言设置
             LanguageSettings languageSettings = Globals.ThisAddIn.Application.LanguageSettings;
             // 获取主语言 ID
@@ -79,8 +77,142 @@ namespace HTEXMark
                         break;
                     }
             }
+            knowledgeUserControl =new KnowledgeUserControl();
+            customTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(knowledgeUserControl, lang.paneTitle);
+            customTaskPane.Visible = false;
+            knowledgeListBox= new System.Windows.Forms.ListBox();
+            knowledgeListBox.Dock = DockStyle.Fill;
+            knowledgeUserControl.Controls.Add(knowledgeListBox);
+            httpClient = HttpClientFactory.Create();
+        }
+        public async void SchoolSelectionChanged(object sender, RibbonControlEventArgs e)
+        {
+            var data = sender as RibbonDropDown;
+            knowledgeListBox.Items.Clear();
+            await AppendSubjectDropDown(data.SelectedItem.Tag.ToString(), httpClient);
+
+        }
+        public async Task AppendSubjectDropDown(string school, HttpClient httpClient)
+        {
+            subjectDropDown.Items.Clear();
+            subjectDropDown.SelectionChanged-=SubjectSelectionChanged;
+            knowledgeListBox.SelectedValueChanged-= KnowledgeListBoxSelectedValueChanged;
+            knowledgeListBox.Items.Clear();
+            var response = await httpClient.GetAsync($"https://rc.teammodel.cn/hita/get-school-data?school={school}");
+            if (response.IsSuccessStatusCode)
+            {
+                string content = await response.Content.ReadAsStringAsync();
+                if (!string.IsNullOrWhiteSpace(content))
+                {
+                    var json = JsonSerializer.Deserialize<JsonElement>(content);
+                    var periodSubjects = JsonSerializer.Deserialize<List<IdCodeNameCount>>(json.GetProperty("periodSubjects"));
+                    if (periodSubjects!=null  && periodSubjects.Count>0)
+                    {
+                        var data = periodSubjects.OrderByDescending(x => x.count);
+                        foreach (var subject in data)
+                        {
+                            var item = this.Factory.CreateRibbonDropDownItem();
+                            item.Label=$"{subject.name}({subject.count})";
+                            item.Tag=$"{school}:{subject.id}:{subject.code}";
+                            subjectDropDown.Items.Add(item);
+                        }
+                        subjectDropDown.SelectionChanged+=SubjectSelectionChanged;
+                        var blocks= await AppendKnowledge(school, data.First().id, data.First().code, httpClient);
+                        knowledgeUserControl.InitializeTreeView(knowledgeListBox, blocks);
+                        knowledgeListBox.SelectedValueChanged+= KnowledgeListBoxSelectedValueChanged;
+                    }
+                    else
+                    {
+                        var itemDefault = this.Factory.CreateRibbonDropDownItem();
+                        itemDefault.Label=$"--------------";
+                        subjectDropDown.Items.Add(itemDefault);
+                    }
+                }
+            }
+        }
+
+        
+    private  void KnowledgeListBoxSelectedValueChanged(object sender, EventArgs e)
+    {
+            var box = sender as  System.Windows.Forms.ListBox;
+            var point =$"{box.SelectedItem}";
+            Microsoft.Office.Interop.Word.Selection selection = Globals.ThisAddIn.Application.Selection;
+            // 获取当前选择的范围
+            Range selectedRange = selection.Range;
+            // 获取当前光标所在行的范围
+            Range lineRange = selectedRange.Paragraphs[1].Range;
+            if (!string.IsNullOrWhiteSpace(lineRange.Text)  &&  lineRange.Text.Contains(lang.point))
+            {
+                string str = lineRange.Text.TrimEnd();
+                string textBeforeCursor = str.Substring(str.Length-1, 1);
+                if ("..、::,,;".Contains(textBeforeCursor))
+                {
+                    selection.TypeText($"{point}");
+                }
+                else
+                {
+                    if (textBeforeCursor.Equals("}"))
+                    {
+                        selection.TypeText($"{point}");
+                    }
+                    else
+                    {
+                        selection.TypeText($",{point}");
+                    }
+                }
+            }
+            else
+            {
+                MessageBox.Show(lang.pointMsgShow);
+            }
+
+        }
+    private async void SubjectSelectionChanged(object sender, RibbonControlEventArgs e)
+        {
+            List<Block> blocks = new List<Block>();
+            var data = sender as RibbonDropDown;
+            knowledgeListBox.Items.Clear();
+            knowledgeListBox.SelectedValueChanged-= KnowledgeListBoxSelectedValueChanged;
+            string tag = data.SelectedItem.Tag.ToString();
+            string[] tags = tag.Split(':');
+            if (tags.Length==3)
+            {
+                blocks= await AppendKnowledge(tags[0], tags[1], tags[2], httpClient);
+                knowledgeUserControl.InitializeTreeView(knowledgeListBox, blocks);
+                knowledgeListBox.SelectedValueChanged+= KnowledgeListBoxSelectedValueChanged;
+            }
         }
+        public async Task<List<Block>> AppendKnowledge(string school, string code, string id, HttpClient httpClient)
+        {
+            var response = await httpClient.GetAsync($"https://rc.teammodel.cn/hita/get-school-knowledge?school={school}&id={id}&code={code}");
+            if (response.IsSuccessStatusCode)
+            {
+
+                string content = await response.Content.ReadAsStringAsync();
+                if (!string.IsNullOrWhiteSpace(content))
+                {
 
+                    List<Block> block = new List<Block>();
+                    var json = JsonSerializer.Deserialize<JsonElement>(content);
+                    if (json.TryGetProperty("code", out JsonElement _code)&& $"{_code}".Equals("200"))
+                    {
+                        var points = JsonSerializer.Deserialize<List<string>>(json.GetProperty("points"));
+                        if (points!=null  && points.Count>0)
+                        {
+                            block.Add(new Block { name="未归类", points=points });
+                        }
+                        //var blocks = JsonSerializer.Deserialize<List<Block>>(json.GetProperty("blocks"));
+                        //if (blocks!=null  && blocks.Count>0)
+                        //{
+                        //    block.AddRange(blocks);
+                        //}
+                    }
+                    return block;
+                }
+
+            }
+            return null;
+        }
         private void SetLang(MarkLanguage language) {
 
             item_mark_tab.Label=language.item_mark_tab;
@@ -116,6 +248,11 @@ namespace HTEXMark
             count.Label=$"{language.count}\n";
             qrcode.Label=$"{language.qrcode}\n";
             user.Label=$"{language.user}\n";
+            item_user.Label=$"{language.item_user}";
+            qrcode.Label=$"{language.qrcode}\n";
+            user.Label=$"{language.user}\n";
+            schoolDropDown.Label=$"{language.schoolDropDown}";
+            subjectDropDown.Label=$"{language.subjectDropDown}";
             //
             single.Tag=language.single;
             multiple.Tag=language.multiple;
@@ -143,7 +280,7 @@ namespace HTEXMark
             ended.Tag=language.ended;
             level.Tag=language.level;
             count.Tag=language.count;
-           
+          
 
 
         }
@@ -151,7 +288,7 @@ namespace HTEXMark
             // 创建 Windows Forms 窗口
             var qrcode_button = sender as  RibbonButton;
             
-            QRCodeForm qrCodeForm = new QRCodeForm(qrcode_button, user,schoolDropDown,subjectDropDown,  lang,this )
+            QRCodeForm qrCodeForm = new QRCodeForm(qrcode_button, user,schoolDropDown,subjectDropDown,  lang,this, customTaskPane)
             {
 
 
@@ -176,12 +313,30 @@ namespace HTEXMark
             // 设置窗体位置
             qrCodeForm.Location = new System.Drawing.Point(x, y);
         }
+        private bool IsCursorAtLineStart(Selection selection)
+        {
+            // 获取当前选择的范围
+            Range selectedRange = selection.Range;
+
+            // 获取当前光标所在行的范围
+            Range lineRange = selectedRange.Paragraphs[1].Range;
+
+            // 判断光标是否在行的开始
+            bool isAtLineStart = (selectedRange.Start == lineRange.Start);
+
+            return isAtLineStart;
+        }
         private void MarkTags_Click(object sender, RibbonControlEventArgs e)
         {  // 在这里根据按钮的标识执行相应的操作
             var button = sender as  RibbonButton;
             string buttonId = button.Id;
             string buttonTag = button.Tag.ToString();
             Microsoft.Office.Interop.Word.Selection selection = Globals.ThisAddIn.Application.Selection;
+            string br = string.Empty;
+            if (!IsCursorAtLineStart(selection))
+            {
+                br="\n";
+            }
             if (buttonId.Equals("compose"))
             {
                 // 获取 Office 应用程序的语言设置
@@ -193,16 +348,16 @@ namespace HTEXMark
                 {
                     case 2052:
                         // 2052 是简体中文的语言 ID
-                        selection.TypeText("{" + buttonTag + "}{综合题结束}"); break;
+                        selection.TypeText(br+"{" + buttonTag + "}\n\n{综合题结束}\n"); break;
                     case 1028:
                         // 1028 是繁体中文的语言 ID
-                        selection.TypeText("{" + buttonTag + "}{題組題結束}"); break;
+                        selection.TypeText(br+"{" + buttonTag + "}\n\n{題組題結束}\n"); break;
                     case 1033:
                         // 1033 是英语的语言 ID
-                        selection.TypeText("{" + buttonTag + "}{QuestionGroupEnded}"); break;
+                        selection.TypeText(br+"{" + buttonTag + "}\n\n{QuestionGroupEnded}\n"); break;
                     default:
                         // System.Windows.Forms.MessageBox.Show("未知的 Office 语言版本:" + languageId.ToString());
-                        selection.TypeText("{" + buttonTag + "}");
+                        selection.TypeText(br+"{" + buttonTag + "}");
                         break;
                 }
             }
@@ -216,22 +371,46 @@ namespace HTEXMark
                 {
                     case 2052:
                         // 2052 是简体中文的语言 ID
-                        selection.TypeText("{综合题结束}"); break;
+                        selection.TypeText(br+"{综合题结束}\n"); break;
                     case 1028:
                         // 1028 是繁体中文的语言 ID
-                        selection.TypeText("{題組題結束}"); break;
+                        selection.TypeText(br+"{題組題結束}\n"); break;
                     case 1033:
                         // 1033 是英语的语言 ID
-                        selection.TypeText("{QuestionGroupEnded}"); break;
+                        selection.TypeText(br+"{QuestionGroupEnded}\n"); break;
                     default:
                         // System.Windows.Forms.MessageBox.Show("未知的 Office 语言版本:" + languageId.ToString());
-                        selection.TypeText("{QuestionGroupEnded}");
+                        selection.TypeText(br+"{QuestionGroupEnded}\n");
                         break;
                 }
             }
             else
             {
-                selection.TypeText("{" + buttonTag + "}");
+                if (buttonId.Equals("remember")||buttonId.Equals("understand")||buttonId.Equals("apply")||buttonId.Equals("analyze")
+                     ||buttonId.Equals("evaluate")||buttonId.Equals("create"))
+                {
+                    // 获取当前选择的范围
+                    Range selectedRange = selection.Range;
+
+                    // 获取当前光标所在行的范围
+                    Range lineRange = selectedRange.Paragraphs[1].Range;
+
+                    if (lineRange.Text.Contains(lang.taxonomy))
+                    {
+                        selection.TypeText( buttonTag+"\n");
+                    }
+                    else {
+                        selection.TypeText(br + "{" + buttonTag + "}\n");
+                    }
+                   
+                }
+                else if (buttonId.Equals("itrue")||buttonId.Equals("ifalse")) {
+                    selection.TypeText(br + "{" + buttonTag + "}\n");
+                }
+                else
+                {
+                    selection.TypeText(br+"{" + buttonTag + "}");
+                }
             }
         }
     }

+ 50 - 103
HTEXMark/QRCodeForm.cs

@@ -22,6 +22,9 @@ using System.Net.Http;
 using static System.Windows.Forms.VisualStyles.VisualStyleElement.Button;
 using System.Security.Policy;
 using System.Xml.Linq;
+using static HTEXMark.QRCodeForm;
+using System.Threading;
+using Microsoft.Office.Tools;
 namespace HTEXMark
 {
     public class School{
@@ -42,7 +45,9 @@ namespace HTEXMark
         public MarkRibbon markRibbon;
         public RibbonDropDown schoolDropDown;
         public RibbonDropDown subjectDropDown;
-        public QRCodeForm(RibbonButton qrcode_button, RibbonButton user_button, RibbonDropDown schoolDropDown, RibbonDropDown subjectDropDown, MarkLanguage lang , MarkRibbon markRibbon)
+        private HttpClient httpClient;
+        private Microsoft.Office.Tools.CustomTaskPane customTaskPane;
+        public QRCodeForm(RibbonButton qrcode_button, RibbonButton user_button, RibbonDropDown schoolDropDown, RibbonDropDown subjectDropDown, MarkLanguage lang , MarkRibbon markRibbon, Microsoft.Office.Tools.CustomTaskPane  customTaskPane)
         {
             this.qrcode_button=qrcode_button;
             this.user_button=user_button;
@@ -50,6 +55,8 @@ namespace HTEXMark
             this.markRibbon = markRibbon;
             this.schoolDropDown=schoolDropDown;
             this.subjectDropDown=subjectDropDown;
+            this.customTaskPane=customTaskPane;
+            httpClient = HttpClientFactory.Create();
             InitializeComponent();
         }
 
@@ -61,7 +68,7 @@ namespace HTEXMark
             // QRCodeForm
             // 
             this.ClientSize = new System.Drawing.Size(284, 261);
-            //this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+           // this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
             this.MaximizeBox = false;
             this.MinimizeBox = false;
             this.Name = "QRCodeForm";
@@ -95,93 +102,62 @@ namespace HTEXMark
             {
                 // 在窗口关闭时打印消息
                 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
-                using (HttpClient httpClient = HttpClientFactory.Create())
+                var response = await httpClient.GetAsync($"https://rc.teammodel.cn/hita/check-login?code={code}");
+                if (response.IsSuccessStatusCode)
                 {
-                    var response = await httpClient.GetAsync($"https://rc.teammodel.cn/hita/check-login?code={code}");
-                    if (response.IsSuccessStatusCode)
+                    string content = await response.Content.ReadAsStringAsync();
+                    if (!string.IsNullOrWhiteSpace(content))
                     {
-                        string content = await response.Content.ReadAsStringAsync();
-                        if (!string.IsNullOrWhiteSpace(content))
+                        var json = JsonSerializer.Deserialize<JsonElement>(content);
+                        token= JsonSerializer.Deserialize<TmdidImplicit>(json.GetProperty("implicit_token"));
+                        schools= JsonSerializer.Deserialize<List<School>>(json.GetProperty("schools"));
+                        if (token!= null)
                         {
-                          var json   = JsonSerializer.Deserialize<JsonElement>(content);
-                            token= JsonSerializer.Deserialize<TmdidImplicit>(json.GetProperty("implicit_token"));
-                            schools= JsonSerializer.Deserialize<List<School>>(json.GetProperty("schools"));
-                            if (token!= null)
+                            var jwt = new JwtSecurityToken(token.id_token);
+                            var id = jwt.Payload.Sub;
+                            jwt.Payload.TryGetValue("name", out object name);
+                            jwt.Payload.TryGetValue("picture", out object picture);
+                            user_button.Label=$"{name}\n";
+                            if (!string.IsNullOrWhiteSpace($"{picture}"))
                             {
-                                var jwt = new JwtSecurityToken(token.id_token);
-                                var id = jwt.Payload.Sub;
-                                jwt.Payload.TryGetValue("name", out object name);
-                                jwt.Payload.TryGetValue("picture", out object picture);
-                                user_button.Label=$"{name}\n";
-                                if (!string.IsNullOrWhiteSpace($"{picture}"))
-                                {
-                                    user_button.Image=new Bitmap(new System.Net.WebClient().OpenRead($"{picture}"));
-                                }
-                                user_button.Visible=true;
-                                qrcode_button.Visible=false;
-                                schoolDropDown.Visible=true;
-                                subjectDropDown.Visible=true;
-                                schoolDropDown.Items.Clear();
-                                subjectDropDown.Items.Clear();
-                                if (schools!=null && schools.Count>0) {
-                                    foreach (var school in schools) {
-                                      var item =  markRibbon.Factory.CreateRibbonDropDownItem();
-                                        item.Label=school.name;
-                                        item.Tag=school.id;
-                                     
-                                        schoolDropDown.Items.Add(item);
-                                       
-                                    }
-                                    schoolDropDown.SelectionChanged+=SelectionChanged;
-                                    await AppendSubjectDropDown(schools.First().id, httpClient);
-                                }
+                                user_button.Image=new Bitmap(new System.Net.WebClient().OpenRead($"{picture}"));
                             }
-                            else
+                            customTaskPane.Visible=true;
+                            user_button.Visible=true;
+                            qrcode_button.Visible=false;
+                            schoolDropDown.Visible=true;
+                            subjectDropDown.Visible=true;
+                            schoolDropDown.Items.Clear();
+                            subjectDropDown.Items.Clear();
+                            if (schools!=null && schools.Count>0)
                             {
-                                MessageBox.Show(lang.unlogin);
+                                foreach (var school in schools)
+                                {
+                                    var item = markRibbon.Factory.CreateRibbonDropDownItem();
+                                    item.Label=school.name;
+                                    item.Tag=school.id;
+                                    schoolDropDown.Items.Add(item);
+                                }
+                                schoolDropDown.SelectionChanged+=markRibbon.SchoolSelectionChanged;
+                                await markRibbon.AppendSubjectDropDown(schools.First().id, httpClient);
                             }
                         }
-                        else { MessageBox.Show(lang.unlogin); }
+                        else
+                        {
+                            MessageBox.Show(lang.unlogin);
+                        }
                     }
+                    else { MessageBox.Show(lang.unlogin); }
                 }
             }
             catch (Exception ex) {
                 MessageBox.Show(ex.Message);
             }
         }
-        private  async void SelectionChanged(object sender, RibbonControlEventArgs e) {
-            var data= sender as RibbonDropDown;
-            using (HttpClient httpClient = HttpClientFactory.Create()) {
-                await AppendSubjectDropDown(data.SelectedItem.Tag.ToString(), httpClient);
-            }
+    
+      
 
-        }
-
-        public async Task AppendKnowledge(string school, string code, string id, HttpClient httpClient) {
-            var response = await httpClient.GetAsync($"https://rc.teammodel.cn/hita/get-school-knowledge?school={school}&id={id}&code={code}");
-            if (response.IsSuccessStatusCode)
-            {
-                string content = await response.Content.ReadAsStringAsync();
-                if (!string.IsNullOrWhiteSpace(content))
-                {
-                    var json = JsonSerializer.Deserialize<JsonElement>(content);
-                    var points = JsonSerializer.Deserialize<List<string>>(json.GetProperty("points"));
-                    if (points!=null  && points.Count>0)
-                    {
-                    }
-                    else
-                    {
-                    }
-                    var blocks = JsonSerializer.Deserialize<List<Block>>(json.GetProperty("blocks"));
-                    if (blocks!=null  && blocks.Count>0)
-                    {
-                    }
-                    else
-                    {
-                    }
-                }
-            }
-        }
+       
         public class Block
         {
             public string name { get; set; }
@@ -192,36 +168,7 @@ namespace HTEXMark
             public List<string> points { get; set; } = new List<string>();
         }
 
-        public async Task AppendSubjectDropDown(string school, HttpClient httpClient)
-        {
-            subjectDropDown.Items.Clear();
-            var response = await httpClient.GetAsync($"https://rc.teammodel.cn/hita/get-school-data?school={school}");
-            if (response.IsSuccessStatusCode)
-            {
-                string content = await response.Content.ReadAsStringAsync();
-                if (!string.IsNullOrWhiteSpace(content))
-                {
-                    var json = JsonSerializer.Deserialize<JsonElement>(content);
-                    var periodSubjects =  JsonSerializer.Deserialize<List<IdCodeNameCount>>(json.GetProperty("periodSubjects"));
-                    if (periodSubjects!=null  && periodSubjects.Count>0)
-                    {
-                        var data = periodSubjects.OrderByDescending(x => x.count);
-                        foreach (var subject in data)
-                        {
-                            var item = markRibbon.Factory.CreateRibbonDropDownItem();
-                            item.Label=$"{subject.name}({subject.count})";
-                            item.Tag=$"{subject.id}::{subject.code}";
-                            subjectDropDown.Items.Add(item);
-                        }
-                    }
-                    else {
-                        var itemDefault = markRibbon.Factory.CreateRibbonDropDownItem();
-                        itemDefault.Label=$"--------------";
-                        subjectDropDown.Items.Add(itemDefault);
-                    }
-                }
-            }
-        }
+        
         public class IdCodeNameCount
         {
             public string id { get; set; }

+ 6 - 1
HTEXMark/ThisAddIn.cs

@@ -7,6 +7,10 @@ using Word = Microsoft.Office.Interop.Word;
 using Office = Microsoft.Office.Core;
 using Microsoft.Office.Tools.Word;
 using Microsoft.Office.Core;
+using HTEXLabel;
+using System.Threading;
+using System.Windows.Forms;
+using static HTEXMark.QRCodeForm;
 
 namespace HTEXMark
 {
@@ -15,7 +19,8 @@ namespace HTEXMark
         int clickNumber = 0; //用于防止多次添加点击事件
         private void ThisAddIn_Startup(object sender, System.EventArgs e)
         {
-            
+           
+          
         }
 
         private void ThisAddIn_Shutdown(object sender, System.EventArgs e)

+ 15 - 3
HTEXMark/lang.json

@@ -34,7 +34,11 @@
     "qrcode": "登录",
     "user": "用户",
     "qrcode_title": "请使用HiTA扫码登录...",
-    "unlogin": "未登录!"
+    "unlogin": "未登录!",
+    "paneTitle": "知识点",
+    "schoolDropDown": "学校",
+    "subjectDropDown": "学科",
+    "pointMsgShow" :"请在知识点标签后添加!"
   },
   "tw": {
     "single": "選擇題",
@@ -71,7 +75,11 @@
     "qrcode": "登入",
     "user": "用戶",
     "qrcode_title": "請使用HiTA掃碼登入...",
-    "unlogin": "未登入!"
+    "unlogin": "未登入!",
+    "paneTitle": "知識點",
+    "schoolDropDown": "學校",
+    "subjectDropDown": "學科",
+    "pointMsgShow": "請在知識點標簽後添加!"
   },
   "en": {
     "single": "MultipleChoice",
@@ -108,6 +116,10 @@
     "qrcode": "Login",
     "user": "User",
     "qrcode_title": "Please use HiTA scan to login...",
-    "unlogin": "Not logged in!"
+    "unlogin": "Not logged in!",
+    "paneTitle": "Knowledge Points",
+    "schoolDropDown": "School",
+    "subjectDropDown": "Subject",
+    "pointMsgShow": "Please add after the knowledge point label!"
   }
 }